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.
I have at long last gotten off my lazy tuchis and updated iCAR to be compatible with Tiger and iChat 3.0. I would like to take this opportunity to apologize publicly to the world as a whole for taking as long as I did. Please do not eat my brains.
Of most pressing note, of course, is that iCAR has suddenly become much less useful. iChat 3.0 now incorporates rudimentary auto-reply functionality. In some respects, you might say that iCAR has gone the way of the Watson, but in truth, this story is not nearly as dramatic as Watson’s or Konfabulator’s. There is, namely, zero lost revenue here. I have decided, however quixotically, that I will continue to maintain and add features to iCAR despite its semi-uselessness because it can do some pretty neat stuff and also out of pride.
Changes
Essentially, release 0.8 of iCAR really only does one thing: it is the Tiger version of iCAR. Under the hood, however, some positively riveting things happened to the code:
- The preference pane was widened to match iChat 3’s panes.
- iChat.h was updated to match iChat 3 and the new InstantMessage.framework.
-
I refactored message-capturing to match iChat 3’s new structure.
- Instead of IMService, I now interface with the new Service class.
- Chats are no longer automatically accepted because they don’t have to be (see “Observations”, below).
- I removed unnecessary mechanism for delaying past chat acceptance (again, see “Observations”).
- Another unneccesary mechanism, this one for accessing status, was removed (the curious, repetitive, and truly nerdy would benefit from another glance below at “Observations”).
Observations
- iChat 3 removes a long-standing annoyance. Previous versions could not send messages if chats were not yet accepted (or, even more infuriatingly, if they were in the process of animating their acceptance). This means that replies are now sent faster, iCAR’s code is much less complex and much prettier, and the software will probably break for fewer people.
- All of the IMService code I patched was apparently moved into the Service class (even the method signatures I hijack are identical). IMService still exists, but it seems to be greatly simplified, presumably because InstantMessage.framework is now a public framework. It provides a nominal interface for interacting with the status values and messages of iChat (really, iChatAgent.app, the protocol daemon). I initially had trouble patching Service using
poseAsClass:, so I eventually elected to use the method swizzling technique well-documented by Mike Solomon of PithHelmet (Greasemonkey for Safari, sort of) fame. - I don’t know if this appeared in IMService at any point in the past, but Service has the class methods
+myStatusand+myStatusMessagefor obtaining global settings about status. Previously, I was hacking a method into the buddy list window controller to get the status. With iCAR 0.8, I had the satisfaction of deleting that pair of files.
Questions
Because iChat 3.0 incorporates basic auto-reply functionality, a iCAR is having a bit of an identity crisis. I’m fairly certain it should stick around, but I am wondering a bit about its role.
- Should it still be called the iChat Auto-Reply? It’s definitely no longer the…
- I should probably stop calling it a “simple” auto-reply feature. (Apologies; that was actually not a question.)
- Should the preference pane and “Enable…” check box continue to use the name “auto-reply”? Now that there are two auto-reply functions in iChat (with iCAR installed), perhaps the term is too generic.
The future
It seems that I will never be short of new features to implement into the next next version of iCAR.
- Demand has increased recently for iCAR to play nicer with the style settings in iChat. That will be Real Soon Now.
- Also sorely lacking is the passage of variables to AppleScripts (variables are currently only passed to shell scripts using environment variables). This needs to happen right-quick.
- Does iChat’s built-in auto-reply functionality set the “this is an auto-reply” flag when it sends its message to the AIM server? If so, can I hijack that in the name of nearly-worthless iCAR progress?
Get it/got it/good
This year, instead of changing “2004” to “2005” in all the copyright notices on your Web pages, be sneaky and change it to this:
Then you can forget about it in 2006. And who doesn’t like to think less?
I’ve just finished setting up Outer Heaven, the weblog of my good friend, John. You may note that its layout looks mysteriously but conspicuously familiar. At the time of writing, the only post is a test one I’ve added, but I expect great things.
Good luck, John, and happy blogging!
MacRabbit’s CSSEdit is what the now graciously defunct Pygmy Software product CSS Suitcase should have been. I may, for example, actually use it — mostly for the extended preview feature.
My most recent paying enterprise has been the design of a Web site for the Association of Bainbridge Communities. (For those to whom this might mean something, the ABC is the organization that puts out Scotch Broom.) Its precise purpose is as yet unclear, but this is what one expects when one works with committees.
I’ve set up hosting for the ABC (they insisted on abcbi.org, a domain I must admit I consider a bit unintuitive), and have completed five variations on a theme that I plan on submitting for consideration tomorrow. I do admit that I am stuck in a design rut — these mockups bear striking similarity to CERTIFIED Jeans and Pygmy Software, my last two projects — but I’m not convinced that’s all bad. I rather like this rut, you could say. It’s a good rut. The kind of rut about which you can say, “Now, that’s a good rut.”
Anyway, if any of my far-reaching and staggeringly inclusive readership is so inclined, please check out the mockups and let me know if you like any, dislike any, and, if you’re feeling generously wordy, why. Is there anything I’m doing totally wrong? Anything that I should absolutely not do away with? Is the guinea pig a rodent (17.4MB PDF)? Is boredom lethal when combined with obsession? What’s with certain Germans and ducks?
Now, dear readers, is your chance to make a lasting mark on your world. Don’t pass it by.
You might say, and you might not be completely incorrect, that I work for Pygmy Software. It would be slightly more accurate, however, to say that I am Pygmy Software. Pygmy is a name that I’ve put on my software for the past six or so years, with the sole purpose of seeming more important than I am.
I’ve just finished redesigning Pygmy Software’s Web site, which was satisfying in itself (static this time — I’ve had enough dynamic sites for a while), but the real highlight here was some shameless nostalgia-wallowing. I did a bit of research and wrote up a pretty-much-comprehensive history of the “company”. If you’re into reading others’ therapeutic musings on their pasts, why not check it out? Otherwise, it would most likely be no more than another very poor way to waste your time. And who doesn’t need one more of those?
I think that RSS makes the world a better place. Most anything that I read on the Web I read through my aggregator, NetNewsWire.
Now, occasionally, there arises the problem that some sites that I, for some reason, enjoy seem to have forgotten themselves in a time where dinosaurs roam freely and mammals’ prime occupations are eating and being eaten. In other words, they don’t have RSS feeds. This elicits one of three responses:
- I grumble quietly to myself and forget the whole incident within thirty seconds.
- I write a screen-scraper in Perl.
- I shave my head and tattoo it with the Greek letter π, made up of a mosaic of the first several digits of the number it represents.
(These responses are listed in order of descending probability.)
I’ve only written a few scrapers, and have only kept two of them, but I’ve now set up a cron job or two in order to share them effectively with the rest of the world.
Thus, and with all possible ceremony, I reveal to you two unreliably-scraped non-compliant RSS 0.92 feeds. They are of the wonderful FactCheck.org (previously mentioned) and Eleet Street, a Mac BitTorrent tracker. Enjoy. Please.
I’m coming just to the end of another exciting and fulfilling consulting job. For some reason, I have taken to naming my jobs using my clients’ last names. Thus, this is the Davison job.
The Davison job is a straightforward web design project for a company known as CERTIFIED Jeans, a small Seattle-based company that manufactures jeans from organic cotton in the United States. Although I’m not one to buy new clothing on a regular basis, they’ve got to be a better choice than your generic McSweatShop Jeans International.
I chose a design that I’d like to flatter myself to think is utilitarian and simplistic, yet eye-catching in a way. I didn’t so much adhere to standards, but it seems to render well rather universally. If you’re in for a thrill and fright, check out their previous design.
This job as been exceptionally enjoyable and satisfying. This may be because of its sharp contrast with most of my web design jobs — content was provided early and clearly, and a function for the site was already in mind. Another element was that I got to work with people who were not only friendly and helpful, but were also startlingly appreciative. By this I don’t mean that they paid well (although they did), but they were surreally enthusiastic about my work, which was good for stroking the ol’ ego and also for motivation.
One odd side-effect of working on the Davison job has to do with the fact that my client used my camera to capture the photos that now grace the site. As usual, I used iPhoto to import the photos, and now my iPhoto library contains eighty-five-odd pictures of… pants. I feel weird.
The job has been an excellent one, and I’d be lucky to have any more like it.
Because I’m beginning to work on iCAR again (finally), I was inspired to go looking for alternative ways to load its code into iChat (it currently uses SIMBL, which is excellent, but I’d prefer not to have to install anything more than the iCAR bundle and it seems like there would be a simple interface for this sort of thing).
I encountered the following options during my research.
-
Unsanity’s Application Enhancer (APE), the best-marketed and most popular method. Daemon-based (
aped). Makes me irrationally nervous in general. The SDK has a wildly restrictive license: “The Application Enhancer license is not compatible with GNU style licenses (GPL/LGPL).” - Zaius, a free (Mozilla Public License) alternative to APE, also daemon-based. Attractive, but I’m not entirely in favor of asking users to install interfaces like this.
-
Input Managers, manifested as the magical Library folder where bundles get loaded into every application. Intended to be for implementations of NSInputManager, but has no restriction on what code can be executed. According to Mike Solomon (author of SIMBL and PithHelmet), these bundles can have troubles selecting the application to load into.
- SIMBL (the aptly named Simple Input Manager Bundle Loader) is Mike Solomon’s solution to instabilities with the Input Managers method. It handles the verification of application identifiers and loads bundles selectively. Yet another required external installation, but resides in only one relatively innocuous directory and doesn’t require a logout or reboot.
-
Ed Wynne’s
libpatch, an aging system for dynamically loading code into Cocoa applications. Breaks more and more with each release of the OS. Virtually nonexistent these days. - Mach calls, including the methods in mach_inject and mach_override, which are best explained in a paper by Jonathan Rentzsch. These require that a running process invoke the calls to the kernel, which means one would need to write a daemon to monitor launches of target applications if one’s override has no external, executable component.
Thus, it seems that I’ll stick with SIMBL until Apple does something drastic. My only real problem with this is that I’ll need to continue distributing two files in my iCAR downloads, but that really isn’t too much of an inconvenience. We have nothing in our pockets. We continue.



