Well, that was quick. A few of the people waiting for Tiger compatibility were sorely disappointed by iCAR 0.8. Instead of crashing when a message was received, iChat (with iCAR installed) became entirely non-functional at startup. The buddy list would not appear, menu items would do nothing, and, perhaps most worryingly, the application menu (the one titled “iChat”) would not even appear.

This happened, however, to a minority of users. iCAR worked perfectly under fresh installations of Mac OS X and iChat, but failed because of some vestige of the previous installation.

Hm, I said to myself, stroking my jutting chin dramatically and narrowing my aging eyes. This sounds eerily familiar.

The help of faithful user Shamir came to my rescue in this singular case. Using copies of his iChat preference property list and an inductive technique that I’ve come to call “change a working installation into a broken installation in little increments until it becomes broken itself”, I identified the offending entry in some users’ com.apple.iChat.plist.

Although I pretended to be startled and even a bit alarmed for the benefit of the swarm of reporters I had by then attracted, I had had a nagging suspicion, almost an intuitive certainty, all along that I would find the root of my troubles in NSToolbar Configuration NSPreferences.

Aside from that it exposed my striking similarity to certain Doylian (which I am certain is the incorrect word) characters, the problem is actually rather interesting and might crop up again for me or someone else, so I’ve decided to write it up here.

Under Panther, a strange problem cropped up that, for some users, would cause the iCAR “Auto-Reply” preference pane to be missing from iChat’s “Preferences” window. Many sleepless nights pointed me toward a strange default in the iChat preference property list of some users:

<key>NSToolbar Configuration NSPreferences</key>
<dict>
    <key>TB Display Mode</key>
    <integer>1</integer>
    <key>TB Icon Size Mode</key>
    <integer>1</integer>
    <key>TB Is Shown</key>
    <integer>1</integer>
    <key>TB Item Identifiers</key>
    <array>
        <string>General</string>
        <string>Accounts</string>
        <string>Messages</string>
        <string>Alerts</string>
        <string>Privacy</string>
        <string>Video</string>
    </array>
    <key>TB Size Mode</key>
    <integer>1</integer>
</dict>

(How or when this preference was created still eludes me.)

In particular, the TB Item Identifiers array was to blame. It defined which preference panes would be displayed in the iChat preferences toolbar. “Auto-Reply”, of course, is not on the list. So, without even consulting NSPreferences, the NSToolbar instance would refuse to display the button that could display a quite dormant iCAR preference pane.

Diabolical.

My solution to this was to hijack the standardUserDefaults class method of NSUserDefaults using poseAsClass:. Whenever anything requested access to the preferences of iChat, iCAR would fetch the standard instance, remove the TB Item Identifiers entry, and pass it along as if it were an accurate reflection of the property list stored on disk.

Equally, if not more, diabolical.

This came around to bite me when users who upgraded to Tiger still had this preference. Something changed in the handling of NSUserDefaults and it was not my or iCAR’s place to tinkering around at its lowest levels. Essentially, I ended up returning a useless value whenever anything needed the standardUserDefaults, which wreaked all manner of unseemly havoc on the running instance of iChat.

Fortunately, it looks like Tiger entirely ignores the TB Item Identifiers entry when dealing with NSPreferences. The old bug suddenly vanished, so the fix for the new bug becomes the happy ending of this tale: I just deleted the two files that implemented the NSUserDefaults hack.

Please excuse the inexcusable gibberish above. I did not intend to put you through it. It might be said that it just poured out.

Regardless, iCAR 0.8.1 — which was fixed only by deleting code — is very available. Binary, source.