Archive for the ‘MacOSX’ category

The Technical Story of the Adium Fixes in Version 0.32

December 31, 2008

Here are the problems I had updating my Adium plugin for version 1.3 of Adium, in the order they were discovered.

First, Adium plugins now must declare a minimum version of Adium. If you don’t say “I require at least version x.x of Adium” then Adium assumes the plugin is too outdated to work and won’t load it. (Turns out that was the right assumption for my plugin!) You declare a minimum supported version by adding a value for AIMinimumAdiumVersionRequirement in your info.plist.

Second, AppleScript support for getting the current status message is broken. So I had to add a way for IMLocation to ask the plugin for the current status message. (It also means that I’m stuck requiring a plugin for any integration with Adium, which is a shame.) For what it’s worth, I prefer the new AppleScript interface for Adium (modulo the “not working right now” bit).

Third, the way plugins are written for Adium has changed. From a software-engineering perspective the changes are for the best, and will make a better Adium. But of course I’m complaining because I had to do more work :-).

Plugins used to inherit from AIPlugin, which had a field named adium that was analogous NSApp. Now plugins conform to the AIPlugin and AIPluginInfo protocols, and can inherit from anything. (Hint: #import <Adium/AISharedAdium.h> will give you the adium back, but now as a proper global.)

Fourth, the way I was updating the status message for Adium wasn’t working so well. And the more I looked into it, the more it looks like very little (if anything) was changed in Adium. It just had a different way of dealing with statuses that wasn’t working out all that well for me.

Solving this issue took me longer then solving all other problems combined. But in the end it was definitely worth it. I have better integration with Adium now. And I was able to get rid of some update-throtteling code of mine that prevented too many changes to the status being made too quickly (Adium is now smart enough to do that internally!).

Fifth, testing, testing, testing. All code that’s written must be tested. And because so many changes were made to Adium as well as my plugin’s code, I waited a few days before officially pushing my changes, to allow more time for bugs to be discovered.

Messages to Nowhere

January 3, 2008

This article has been updated, and moved here

NSWindow setResizable:

December 18, 2007

This article has been updated moved to a new location.

NSWorkspace Bug in – openFile: ?

December 7, 2007

EDITED TO ADD: I could reproduce this bug in a large project, but not isolate it in a smaller one. It is much likely for my code to have a bug then NSWorkspace. I’m still not 100% certain that this issue wasn’t my fault in some way I don’t understand. But no matter what caused the bug, the work-around I describe here has been working for me. Please let me know if you have this same issue as well, or any insight into what I could have done to cause it.

The Problem:
I need to launch a background-application from inside the application-support directory. The OS is Mac OS X 10.5.1 build 9B18.
[[NSWorkspace sharedWorkspace] openFile:path];
where path is the correct path to the application, in my case “/Users/user/Library/Application Support/IMLocation/IMLocationHelper.app.”, works about 3 out out 4 times, but intermittently fails. It also reports success without actually launching IMLocationHelper.app, but this is far more rare.

Details:
When openFile: explicitly fails, it prints, “LSOpenFromURLSpec() returned -600 for application (null) path /Users/user/Library/Application Support/IMLocation/IMLocationHelper.app.” to stderr.

Error -600 is procNotFound /*no eligible process with specified descriptor*/.

The path is correct, the application exists there. I verified this by
assert([[NSFileManager defaultManager] fileExistsAtPath:path]);
before calling openFile:.

Calling openFile: again immediately after a failure often works

Also, while(![[NSWorkspace sharedWorkspace] openFile:path]);
will terminate, meaning it reported success at some point, but it will not always have actually launched the application at path.

(EDITED TO ADD: At first I thought that, NSWorkspace was probably opening IMLocationHelper, but not blocking until it has finished being launched. But sleeping, to give IMLocationHelper time to finish launching, did not solve the problem.)

performSelectorOnMainThread did not solve anything ether.

I verify that IMLocationHelper has been launched by
assert([[ShellTask executeShellCommandSynchronously:@"ps -axww | grep IMLocationHelper | grep -v grep"] length] > 0);

A Workaround:
[[NSTask launchedTaskWithLaunchPath:@"/usr/bin/open" arguments:[NSArray arrayWithObject:path] waitUntilExit];.

This calls the open command to launch the application. I have not been able to make it fail when path exists.

Crash Logs

December 7, 2007

Daniel Jalkut on how to get the most out of crash logs. It’s good advice.

Actually I do have one big issue with the article:

If there’s one behavior of your application that you should focus on eliminating, it’s the behavior of crashing. Above all other “nuisances,” this is the one that is absolutely unacceptable.

But preserving someone’s data is more important then crashing. Having to rewrite your paper because your PC devoured it is worse then crashing. Crashing may be the worst “nuisance”, but there are more important bugs to squash first. However that is a topic for another time — we all agree that crashes are a problem should be fixed.

Although Daniel shows how to synthesize debugging symbols from hex-address, I think it’s worth considering leaving debugging symbols in your shipping app.

The reasons for [building applications without debugging symbols] are mostly to keep the shipping application as small as possible, but there are also some good reasons to hide the symbols if they reveal too much about your business strategy.

I can’t say anything about your business strategies, but removing information that can help you diagnose problems “in the field” seems like a very bad trade-off for slightly smaller files.

Hard-drives cost about $0.30 per gigabyte (GB), and the price is still falling fast*. Because the GB is the unit hard-disks are sold by, I am going to use it instead of MB or KB; I think it puts file-sizes into the right perspective.

Today’s applications are “big”, for a very good reason. That article says it better then I can, but the gist of it is that megabytes are cheaper then air and bigger programs can do more, making them more useful (the cost of a GB of storage space has fallen over 20 fold since the article was written, by the way).

The largest program I use every day that was built with debugging symbols on is EyeTV. It weighs in under 0.11 GB, and I don’t consider that “bloated”, because I get good value for my 3 cents of disk-space. Stripping debugging symbols with strip makes it 0.0076 GB smaller. That translates into $0.002 worth of hard disk, that could store 13.7 seconds of TV . And that is insignificant. A few thousandths of a GB make little difference, and that’s all stripping debugging symbols will get you.

Of course, this is all academic if no one ever sees the crash-logs. Unfortunately, developers know, that’s the current crappy state of affairs. Crash reports are sent to Apple, and only Apple. The developers who wrote the program — the ones who could best fix the problem, and who desperately want to know about it, are completely out of the loop.

If Apple passed crash logs on to developers, everyone would win. Developers would be able to squash more bugs in less time. Users would have a better, more productive and bug free, experience. Apple could sell those improvements. Microsoft already does this, and it seems to work well for them. Most people are unaware of this SNAFU, and probably think that reporting the crash to Apple gets the information to the right people. I don’t know if educating people about the issue would light a fire under Apple, but it might.

—-

If enough people start using flash memory over current magnetic-platter harddrives, then the price-per-GB ratio could change, because flash is currently about 100x more expensive (per GB). But the trend of the current storage-medium’s price exponentially falling will continue

Flash-based notebooks are already here, but they aren’t popular, yet.

But by the time flash-based computers become popular, their cost-per-GB will probably be as good, or better, then full-sized hard drives of today. Tiny hard-drives, using conventional magnetic platters, like the ones in the iPod, are also a compelling alternative to flash.

Useful MacOSX Terminal Commands

November 16, 2007

This post has moved here.

Design Process: Current Location “Headline”

November 10, 2007

This is a bit of the design process behind one line of one settings panel inside IMLocation.

The “Locations” panel controls everything having to do with to locations. The pane’s “headline”, outlined in red, shows what is assumed to be the current location.
The Locations Panel

It reads like “Your current location is home”. It does not say “You are: Home”, or “You are at: Home”, even though that’s shorter, and closer to the familiar “you are here” stickers. “You are at:” is out, because people need to be free to choose whatever names work best for them. Naming a job-location “working” should not turn the headline into nonsense like “You are at: working”. I choose not to go with “you are: …”, because it felt too imperative — like it was dictating what the user was doing. I wanted the copy to say “This is where the program assumes you are”. I’m still not 100% sure that this was the right phrase to use, but it is clear, and it works well enough.

Immediately to the right of the headline is a button, “That’s not where i am…”, which lets the user fix things if the presumed location isn’t where they are. The button is on the same line as the the headline, because I think this makes it a little more clear that the button corrects the current location. Putting it under the headline would separate it from the current location.

I wanted clicking on the headline to select the current location, so it could be edited. This seemed like a very intuitive action to me, but affording it turned out to be surprisingly tricky.

Starting with v0.20, I made the entire headline a giant button, with a different style then the “That’s not where I am…” button:
Current Location v0.20

This showed that it was clickable, but looked kind of ugly, and testing showed it wasn’t clear to all users what clicking it did (“Why is that a button?”).

To clarify, I made only phrases that meant “the current location” clickable.

Mock-up 1:
mockup1

Mock-up 2:
mockup2

This was a big improvement, but still not good enough. The button’s borders broke up the text, making it choppy and slow to read. The “current location” button looked ugly and wrong, because normally buttons in OSX start with a capital letter. But capitalizing words in the middle of a phrase would be even more dissonant.

At this point I realized traditional buttons just weren’t a good fit. Every other button in the interface modified a location, but the buttons in the headline just select something. They don’t change anything. Every button I’ve ever seen in a good interface makes something happen — it changes data, or how data is presented, or searches billions of web-pages. I needed something a little less “heavy duty” then a button, that still afforded clicking, but didn’t break the flow of text.

Hyperlinks were a great fit. Clicking them means “show me that” — which is exactly what clicking the location headline was supposed to do — show something. They afford clicking, without breaking the flow of text.

So starting with v0.27 I made the key phrases links inside the headline.
v2_7_tiger.jpg
I also put the “That’s not where I am…” button and the headline together in a box, to help re-inforce their relationship, and to give the headline some emphasis by giving it a border.

Under Leopard, the headline looks like:
v2_7_leopard.jpg

Leopard introduced a new button style, called “Recessed Button” in Interface Builder, that is a perfect fit. It has no border, and hilights on mouse-over, just like a hyperlink. (Basically, it’s what is used in the Safari Bookmarks bar).

Right now I’m leaning towards dropping support for Tiger, so that I can take advantage of the UI improvements in Leopard. I just wish I had a better understanding of how many users that move would alienate.