Solipsism Gradient

Rainer Brockerhoff’s blog

Browsing Posts in Development

Positive feedback on Nudge is mounting. There’ve been over 3000 downloads so far in 3 days, beating XRay‘s 2800 and Zingg!‘s 2000+ downloads over the whole month!

c.k. over at 3650 and a 12-inch links to Nudge and suggests:

Apple should send him a rather large donation for providing a solution to one of their major Finder bugs…

Not that I would mind… 😆

I’m sure that the Apple folks are working hard at this. However, from the rumor sites, it seems they’re stretched rather thin at the moment, working on Mac OS X 10.3.3. Also, Nudge is more of a stop-gap solution; I certainly wouldn’t want it made permanent.

The links and referrals stemming from John Gruber’s article are becoming too numerous to list. This shows, once again, how word of mouth is important for Mac developers. I also found a flattering side-effect at Ryan Wilcox’s h4ck3r+=boi:

Brent Simmons has created a Mac Software Business mailing list on Yahoo Groups.

The description: “This group is for small, independent Macintosh developers who want to talk with other developers about the business of Mac development. Questions on pricing, packaging, advertising, e-commerce providers, and so on are on-topic. Note that this list isn’t a vehicle for promotion: announcements and press releases are off-topic.”

The members of the group include some heavy hitters in the Mac Software industry, in addition to Brent: Rainer Brockerhoff, Michael Tsai, along with a cast of additional others.

Brent’s mailing list seems to have great potential; if you’re a shareware/indieware developer, I recommend it highly.

Slava of Unsanity posted part I of a good article about being successful in what he calls “Indieware” (formerly known as shareware) – reasonably-priced software developed by small companies, or individual developers such as myself.

First thing to ask yourself is how useful your software would be? Would you use it? Some people I know are making software they don’t use personally and try to sell that (OK, “day job” work doesn’t count, I am talking about indieware here and in the rest of the article). My vague point is that the product will not sell good enough if you do not use it yourself daily, or see no real use for it, or are not inspired enough to use it. Call me superstitious, but how you feel about your software creation is more or less how users will feel about it, except they will have less love and tender feelings than you do towards it.

Some younger developers I directed to the article found this point too self-evident, but it’s not!

Erik J. Barzeski also agrees it’s not self-evident:

Successful indieware developers “get it.” They’re Mac users to the core. Mac users are picky. They have high standards. Mac users care about the whole experience – is your site great, icon cool, and application dock-aware? “Where’s my damn AppleScript support!” they’ll ask. Do your keyboard shortcuts meet their expectations? Is your toolbar pretty? Do you even have a toolbar?

If you’ve been using a Mac for five years or more, you “get” this already. You’re a picky sonofabitch too, and you despise crap applications,especially if they’re your own. Indieware developers spend an inordinate amount of time thinking about the above issues and more during development – great UI doesn’t just fall from the sky. Slava says that new developers should not “?be ashamed to spend a week or more in the planning stage.” I say they should be ashamed (and will be shamed) if they only spend a week. Planning never ends. Mac users expect nothing less.

Couldn’t have said it better myself.

Slava also links to The Do’s and Dont’s of Shareware and Software Strategies for Emerging Developers, two other must-read articles. Now to wait for part II…

Re: One more…

No comments

Well, the details caught up with me very fast. By late afternoon, one user e-mailed me a crash report for Zingg! 1.4. After dinner, another user e-mailed me with a simple way to reproduce the crash. 30 minutes later it was fixed, so 1.4.1 has just been published.

This sort of thing is very embarrassing… neither I nor my handful of beta-testers thought of doing the particular choreography that causes the crash. Namely, one has to:

  • set either DropStuff or Disk Copy to “always/override”;
  • set the “Show” popup to either “No comment” or “Styled name”;
  • open the contextual menu and the Zingg! submenu;
  • without releasing the mouse, go outside the submenu to close it;
  • still without releasing the mouse, go back and reopen the submenu. Boom, as Steve Jobs is fond of saying.

Actually, any application which has exactly 8 or 9 letters and which starts with any hexadecimal digit would cause the crash, but only DropStuff (and, for Jaguar users, Disk Copy) fall within these parameters. At least of the applications I have here.

OK. Why can such a weird combination of circumstances trigger a crash? The answer lies within the way Contextual Menu Plugins work. Briefly, the plugin is a loadable bundle with a few precisely defined entry points. When the user control-clicks (or right-clicks) on some item(s), the “Examine Context” entry point is called with a list of AppleEvent records – one for each item. Such a record resolves to a file path or URL. So I have to loop over the list and by a somewhat complex logic return another list containing parameters for the items I wish to have inserted into the Finder’s contextual menu.

These parameters unfortunately are somewhat restricted; I can pass the menu item’s text, a so-called command-ID, and a few attributes for the item. Later on, if the user selects one of my menu items, the “Handle Selection” entry point is called, this time with that item’s command-ID, and the same list of records that was passed to the first call I described. At this point, I decode the command-ID to get back which application I should open, and I re-decode and encode the record list to pass the list of items to be opened to that application.

All very well, but how to attach application icons to each menu item? This demands more complicated hackery. First, I had to register yet another entry point: a “Menu Event Handler”. Unfortunately, this gets called for the main contextual menu and for every submenu – not just for my own little submenu! So first I had to detect my own submenu among the others; not easy when contents are wildly variable. I finally hit upon the trick of setting an invisible first item with a special encoded title.

Also, for some weird reason, at the point this handler gets called the command-IDs haven’t yet been attached to the menu items – so there’s no way of telling directly to which application each item corresponds. So I simply encoded that information into the menu item texts I return from the “Examine Context” entry point, instead of putting in the actual application name. When the handler sees such an encoded text, it decodes it to obtain the application path, and from that gets both the name and the icon, and puts them into the menu item.

What I conveniently forgot is that the handler gets called every time the submenu is opened – not just when it’s built. So the second time around, the handler dutifully tries to re-decode the menu items again – only now they already contain the actual application names! And for certain names, the decoding will actually proceed with invalid data and crash later on. So, a simple first-time flag and it was fixed. For some reason, in my tests I never played around with the mouse, opening and closing the submenu…

I’m glad to read that my old pal Stan Kelly-Bootle is back from serious (heart?) surgery, as told in his latest Son of Devil’s Advocate column. Stan’s apparently back in form, at least verbally:

With the first major break in my monthly Devil’s Advocate (DA) columns and the Son Of DA (SODA) progeny since May 1984, it seems logical to call this new sequence ROSODA (Return of SODA)? I rather like the Japanese resonance. Losoda is the wife of the head warrior but has the other six on the side. Just a brief Samurai of the plot.

In the linked-to column, Stan also has a very long and learned, but extremely entertaining, review of Clifford Pickover‘s book Keys to Infinity – I have several of Pickover’s books, but not that one. I’ll certainly put it onto my wish list.

I’ll also seize the occasion to plug Stan’s seminal work, The Computer Contradictionary, a copy of which he kindly signed for me when I visited him at his former home north of San Francisco in September 1999. No programmer should be without a copy.

Zingg! out…

No comments

Well, Zingg! 1.3 is out.

It took a few days longer than I expected. First there were some more bugs and suggestions; then I tested it on Jaguar and two things didn’t work at all; and finally I had a run-in with configuration problems for my local database server. If you’re wondering about the last item, it’s because Zingg! 1.3 now incorporates the latest version of my online version-checking code… which incidentally feeds me the user’s version of Mac OS X for my statistics.

As I type this, the VersionTracker page counts 387 downloads. If past stats are any indication, that means about 800 or 900 downloads total… many people go directly to my site. My site statistics run every midnight, so I have no exact figures yet. Meanwhile, 206 of those people (let’s say 25%) used the new version-checking code. 204 are on Mac OS X 10.3.2, 2 are on 10.3.1. No earlier versions at all! I’ll have to check whether this is a bug or a reliable statistic…

Then again, this is good news, as I’d like to do Panther-only software in the near future. I’ll try and hurry up the next version of XRay to get stats from those users, too.

The Jaguar incompatibilities were quite puzzling. The Zingg! Configurator relies on a main NSTableView to show a list of applications. I wanted to allow the user to sort the table by any of the 4 table columns. The standard way of doing this, by clicking on the column headers, seemed simple to implement. Since I used NSURL objects to store the application names and paths, I subclassed this to store a complete table row in each object and then used the standard NSArray sortedArrayUsingSelector: method to sort this in different ways. It worked on the first try on my Panther development machine… but then in Jaguar it threw an exception indicating that my subclassing wasn’t working at all.

This was complicated by the fact that I’ve migrated all my projects to Xcode, so I couldn’t use a debugger on the Jaguar machine… but I finally found some hints that the NSURL internal workings had changed significantly from Jaguar to Panther – apparently it used to be a class cluster, but wasn’t anymore. To save time, I changed from a is-a to a has-a pattern for my table row object, and this worked again.

Then I ran into a Jaguar bug: the delegate tableView:didClickTableColumn: method isn’t always called, unlike in Panther. The workaround is to turn on the option to allow column reordering (by drag&drop) – I thought it kind of useless but found no other way.

Then (after already uploading the disk image) I had to go back and rewrite the docs for the changes… c’est la vie. At least it’s out now and no bug report’s arrived so far…

Cheeky Error Messages

No comments

I’ve never been more than an occasional user of Apple’s MPW (Macintosh Programmer’s Workshop). I thought it was defunct but apparently Apple’s still supporting it for development on older Classic systems.

Anyway, one thing I recall is that the MPW C compiler had some funny error messages, and this post on Ztuff reminded me of that today. Some nice ones:

“…And the lord said, `lo, there shall only be case or default labels inside a switch statement'”

“a typedef name was a complete surprise to me at this point in your program”

“This label is the target of a goto from outside of the block containing this label AND this block has an automatic variable with an initializer AND your window wasn’t wide enough to read this whole error message”

“Too many errors on one line (make fewer)”

I promptly looked up the latest official version of MPW on my Apple Developer CDs (August 2001, if you’re interested) and the latest compilers, unfortunately, seem to have been expurged – there are only the usual dry “illegal whatnot found” messages. I’ll have to see if I can find an older edition.

Unfortunately this sort of humor seems to be increasingly rare. The closest thing I could think of in currently shipping software are the ICQ client connection messages:

First we’ll need an ICQ server…

I’m sure I saw a server somewhere…

Attempting to make sure you are who you say you are…

Now, let’s sort out this little issue called ‘logon credentials’…

Doing something complicated…

Waiting in line with millions of other users…

So much data, so little time…

Fulfilling the server’s endless requests…

Initializing all kinds of protocols…

How fussy can you be about one insignificant connection?

Now comes the tricky part…

Seems like the server is a little picky today…

We’re in. Have fun.

Craftmanship

No comments

Joel Spolksy has a new, unfortunately all-too-brief, article out: Craftmanship. As most of Joel’s articles, this should be required reading for any shareware developer.

It comes down to an attribute of software that most people think of as craftsmanship. When software is built by a true craftsman, all the screws line up. When you do something rare, the application behaves intelligently. More effort went into getting rare cases exactly right than getting the main code working. Even if it took an extra 500% effort to handle 1% of the cases.

Reminds me of when I moved away from home and asked my father (a master carpenter) to check out some furniture I was considering for my apartment. He always reached underneath to check if there were any rough edges – and there always were. He said a true craftsman always sandpapers all edges, even the ones nobody can see.

“But no one else would know!”

He would know.”

Exponential Income

No comments

I was tabulating the income from XRay registrations and thought the graph might be interesting for other shareware authors:

The initial peak is probably due to the fact that I had a relatively long public beta period – about 6 months, if I recall correctly – so the product was already well-known when 1.0 came out. I suppose that software released without a public beta would have a registration peak some weeks after release. After such a peak, if the product is left alone, registrations fall exponentially, approaching but never quite reaching zero.

The 1.0.5 release seems to have been well-timed; the curve had already stopped falling steeply and there was demand for new functionality, so the new version attracted a number of new clients. Publicity was favorable and XRay had been included on several CDROMs (some of which published the previous version), so there was a new, shallower peak.

For various reasons I then stepped on the ball, as they say here, and essentially left the product alone for nearly a year, except of course for user support. I should have begun working on 1.0.6 (or even 1.1) immediately, aiming for a release date around November 2002, to jack the curve up again. When I finally went back to the old drawing board a couple of months ago, the initial buzz about the product had long died down, and some of the functions which made it attractive when Mac OS X 10.1.x was new had been gradually added to later releases over time.

So the slight peak for the recent string of releases is due solely to some new users attracted by the release notices; there’ve been no reviews for some time, though I believe a couple will come out now. So part of the lukewarm reception is probably due to a lack of proper publicity; the bulk of downloads, from what I gather from my e-mail statistics, was from already registered users.

So the correct strategy now seems to be, release 1.1 with sufficient additional functionality to attract a substantial number of new users, and generate sufficient publicity around it. I’m working on that…

Photos licensed by Creative Commons license. Unless otherwise noted, content © 2002-2024 by Rainer Brockerhoff. Iravan child theme by Rainer Brockerhoff, based on Arjuna-X, a WordPress Theme by SRS Solutions. jQuery UI based on Aristo.