WordPress for the iPhone

July 22nd, 2008

Now I can blog on the fly with a new toy for my iPhone! Weeeeeee…

Another gotcha to remember.

July 17th, 2008

For some reason a development profile seems tied to the computer as well as the specified phone on the iPhone. What this means is that when you move the device from one computer to another to work on some software (say, a personal laptop to a personal desktop and back again), you need a way to clear out the development profile before things will work again.

I learned this the hard way yesterday when I blew away the contents of my iPhone, only to have things not work correctly (and deleting all my music at the same time).

Turns out the profile certificates are accessible and can be deleted from the iPhone itself: under “Settings” navigate to “General”, then scroll down to “Profiles”: this will show a list of profiles installed on the device which can then be deleted. Delete your development profile(s) from the device before plugging it into the new machine, and Xcode will load the profile for that platform onto the iPhone and things will just work again.

I survived the Great iPhone Line of 2008.

July 11th, 2008

Nine and a half hours.

Nine and a half friggin’ hours!

If it weren’t for the fact that I absolutely needed a device so I could test some location-aware software on the gadget, I would have never bothered.

Meh.

It’s why God created tool tips.

July 1st, 2008

Don’t hide or disable menu items.

This is what separates the User Interface men from the User Interface boys: the suggestion “Instead, leave the menu item enabled. If there’s some reason you can’t complete the action, the menu item can display a message telling the user why” is the most Gawd-aweful suggestion I’ve heard in a long time.

The correct answer, of course, is to create a tool tip which pops up over the disabled item which indicates why the item is disabled. That way we have instant feedback on what a user can do, and if the user is puzzled, he can easily discover why a particular item isn’t currently selected.

In Java, you can do this by calling JMenuItem.setToolTipText(); set the value to an explanation why the menu item has been disabled, and the explanation will pop up when the user hovers over the disabled item.

On the Macintosh, with Cocoa you can do this by setting the ToolTip text field in the IB .xib file with the text describing the item; call NSMenuItem’s setToolTip: method in order to update the text for the disabled menu item.

And even Windows has the ability to create tool tips for disabled menu items, though it takes a hair more work: by watching for WM_MENUSELECT notifications you can then pop up a CToolTipCtrl, or update a status bar text line, showing the appropriate text if the item is disabled.

So as much as I appreciate Joel’s comments on the software development industry, on this particular item, ummmmm… No. I agree more with John Gruber: you’re much better assuming your users are clever. But if your menu command structure contains commands which are just odd or hard to puzzle out at first glance, tool tips are much better than an idiot modal dialog box. It’s just more elegant.

Self employment health care

June 9th, 2008

The first thing I did as a 42-year-old with a wife when I left my job to go down the self-employment route was to get health care insurance. And boy is it complicated!

To summarize, I managed to get Aetna with a moderately high deductible ($5k/year) for both of us for around $300/month.

What made the decision making process complicated is not really understanding the various deductions and coverage exemptions. But it boils down to this: the various Aetna plans essentially have two rate structures. The first rate structure is when you see people who are part of the Aetna system; the second is for those who are not part of the Aetna system. And each rate structure includes a deductible (the maximum you will have to pay out of pocket for medical care per year), a “major medical” deductible (the maximum additional amount you’ll have to pay out of pocket if you get something like surgery), a visit co-pay (what you’ll have to pay when you see a doctor) and a prescription co-pay (what you’ll pay for a prescription). Each of these four numbers (deductible, major medical deductible, co-pay, prescription) is repeated twice: once for in-system and once for out-of-system. Once you’ve hit the deductible, of course, Aetna covers the rest up to $5 million–at which point, I presume you’re screwed. (A friend of mine died a few years ago; his medical bill exceeded $1 million for a 90 day stay in the hospital with a constant stream of tests and the attention of a whole bunch of specialists. That means that while a $5 million cap isn’t impossible to hit, it’d require a pretty nasty health care disaster on the scope of 15 months of hospitalization.)

Each of the different plans I saw from other companies looked roughly the same: about a dozen or so confusing numbers–but all of which boil down to your own responsibility before the health care package kicks in. (I only went with Aetna because I was covered by Aetna when I worked for Yahoo! and Symantec, so I wanted to keep things simple.) Ultimately, however, after wading through each of the numbers, health care insurance boiled down to how much I was willing to pay each month verses how much risk (how high a deductible) I was willing to live with. For someone who is self-employed with a huge pile of savings, it seemed a high deductible made the most sense: in the event of a disaster I can easily write a check for $8k (my max out of pocket if I’m hit by a bus, which is the deductible amount plus the “major medical” deductible on my policy), but in the starting stage of my startup, I’m not making any income.

Mixing Objective C and C++… Heh

June 9th, 2008

I just wrote:

return tasks[[value intValue]].objectID;

Heh heh heh heh heh…

(For those who don’t understand, I just called a std::vector array operator[] method for the array ‘tasks’ with the return value of an Objective-C invocation of ‘intValue’ on the NSNumber value.)

Java sucks and Objective-C is great? Puuuhhhllleeeeaaassseee…

May 28th, 2008

I still remember the brouhaha raised over Java on the Macintosh, and pronouncements by many of the Macintosh Technorati that Java sucks. (I believe Gruber’s words were Cross-platform crippity-crap Java apps.)

By all of the various posts I’ve seen, I’d think that Java was a complete wasteland while Cocoa was the rolling green hills of programmer nerdvana.

Okay, that’s fine. I set forth building a new custom application for the retail market, and faced with the various choices for building a cross-platform system I decided to build a simple data core in C++ with the Mac UI in Objective C++ and Cocoa, and the Windows UI in MFC/C++. (The common data core is to assure that data can be easily shared, but is a very small kernel: perhaps right now about 10% of the overall code base. So I’m not trying the YAAF-lite solution of building a UI framework on top of Objective C++ or MFC; rather, I’m building the UI twice, with a common set of data accessor routines at the bottom of the stack.)

Nerdvana? Hardly.

Today’s fun-filled afternoon was spent trying to figure out how to do an easy gradient fill for a custom control so it doesn’t have a flat, 2D appearance. With the sheer beauty of the Macintosh UI environment, you’d think would come convenience routines–but not really: the amount of work to build a gradient filled background was about what I’d expect using the Graphics2D class in Java.

And I’ve come to a couple of conclusions while engaging in this little exercise.

(1) The advantages outlined in Jens Alfke’s essay about making superior interfaces only gets you half-ways through the front door. To make it across the finish line requires a lot of nit-picky detail work that the Macintosh Cocoa libraries only sorta help you with. Sure, there is plenty of support for animation stuff which is really freakin’ cool. But to draw my simple gradient in a way which was portable back to MacOS 10.4 (and my business app needs to be supported by the current version and the previous version of MacOS X) required about 120 lines of code–which, while it took a couple of hours to toss together and test, wasn’t the easy exercise that many Cocoa advocates seem to suggest awaits all who come to the Cocoa big tent.

This isn’t to say that there aren’t advantages to Cocoa over Java Swing or MFC. However, there are many places where Java’s framework has a clear advantage: the JScrollPane class, for example, is a lot more flexible to work with than the NSScrollView class. And don’t even get me started on NSTreeController, though Rentzsch’s comments on enabling NSZombieEnabled was a god-send.

A corollary to this is:

(2) Macintosh applications look great because Macintosh programmers sweat the details, not because the Macintosh environment makes sweating the details any easier than in Java or Windows MFC. It could very well be the Macintosh market: people expect pretty applications, and so a lot of attention goes into making pretty applications on the Macintosh. This attention to detail, however, doesn’t really exist in the Windows market–and don’t even get me started on Enterprise Java applications. (I will agree with Gruber on this: a lot of Java Enterprise Swing applications do look like crap.)

However, this does not mean that the look and feel of Java applications are doomed, any more than it means Cocoa applications are uniformly great–nor does it mean to get the same level of greatness on a Java application you must spend two or three times more effort than on a corresponding Cocoa application. (And it’s not like Cocoa has inherently better support for creating icons like Panic’s beautiful icons, as opposed to the type of 1980’s icons you see in Java: nowadays they’re both PNG files.)

This attention to UI detail, by the way, predates Cocoa, and even predates NeXT, as anyone who ever read the original Apple Macintosh Human Interface Guidelines would attest. In fact, if anything, NeXT programmers and Cocoa programmers prior to the Apple merger weren’t exactly producing stellar examples of UI goodness: I’d say the biggest problem that I saw as an outsider when Apple and NeXT merged was having Apple’s attention to UI detail and usability drilled into the NeXT programmers–much to their shock. Even today I’d say that Apple’s attention to UI detail is only about 90% of what it used to be in the Mac OS System 7 days.

And that attention to UI detail wasn’t because Mac OS System 7 was a fantastic object-oriented development environment. (I should know; I was writing software for System 6 and earlier.) It was because you would sweat details like the fact that on System 6, an OK button was offset 14 pixels–not 15, not 13, not 8–from the lower right of the screen and was 58 pixels wide, not 57, not 59. (Now I will say that System 6 was superior in one aspect to Microsoft Windows–a superiority which existed for quite a few years: Macintosh QuickDraw’s CopyBits() routine was light-years ahead of any bit blitter available on Windows or on X windows: it would anti-alias, crop, stretch, extrapolate, and even fold your laundry and put it away for you, giving the Mac OS System 6 platform a clear advantage over Windows 3.1. But Windows and X windows caught up in that department long ago.)

So anyone from the Macintosh Technorati who suggests that Cocoa is inherently superior–I’m used to religious wars, even from people who should be intelligent enough to know better.

Oh, and for the curious, I’ve attached my GraidentFill class in Objective C using the CGShading routines to handle my custom control shading. It’s really not as flexible as the 10.5-only NSGradient class, but it does the trick.

Common edit design pattern.

May 24th, 2008

Messaging is an important aspect of application development, especially in a UI-driven application.

While working on the undo architecture of an application I’m putting together, I ran into an interesting problem, and a general-purpose architecture which could handle this popped into my mind, that I thought I’d jot down for future reference. Feel free to borrow the idea if it seems useful, and pardon me if the idea is blindingly obvious.

A typical editing architecture essentially can be represented as a state S which represents the current state of the document, and a set of messages fi which transforms the state Si to a new state Si+1. Each message f represents an editing change to the document S.

Now a typical undo architecture handles undoing messages by storing the creation of messages f’ which is the inverse of f. When an edit operation f is generated and document S is transformed, an inverse operation f’ is created (in practice, as part of the code implementing the change message f) and added to a stack of undo operations, which can then be used to undo the operation on S. In theory as long as each operation has an inverse, we can maintain a perfect undo stack. In practice, of course, user considerations muck up this perfect world: for a text editor, for example, individual keystrokes f(key) may be coalesced into a single insert operation for purposes of an undo operation. (In that case, the easiest way to maintain this undo state is to allow the code creating the f’ function to peek at the top of the undo stack, to determine if the existing top of the undo stack can simply be extended.)

A second thing that one can do with messages f to a state S is that you can then use those messages to determine if S has changed, in order to update the user interface element displaying the document S. For example, if you have two text editors opened to the same document, each keystroke f(key) can trigger a message from S (call it ui) which triggers a user interface update.

Now I was working on an application which had multiple user interface elements editing the same object, and I was generating messages ui which was being used to update my user interface elements. The bug I had was that, when I would edit a state, the user interface would be updated–because my UI handling code would do:

    myDocument.sendEditRequest();
    updateMyUserInterface();

And of course on undo, the undo code would do the equivalent of:

    myDocument.sendEditRequest();

It strikes me that there are two solutions to this problem, though unfortunately most UI frameworks I’ve encountered makes the second solution a bit harder to implement in a natural way.

The first solution is to always use the state changed messages ui in order to drive the user interface refresh cycle. Sometimes this may not be the easiest thing to implement, however: some basic controls (such as check boxes and radio boxes) update their state automatically and really, updating their state again on receiving a state changed message is redundant.

The second solution is, on creation of an edit change request, to automatically note in that request the source of the change: thus, one of the parameters of a change request f is the originating object that sent the change. (For an undo change, the requester would be set to a value indicating that the message came from the undo manager.) The state changed messages would then pass the source of the change request on in the ui messages, so that a user interface element receiving the message can then choose to ignore the message if needed.

I personally like the second solution better than the first; the added flexibility allows my user interface control code to decide how to handle a state change. Unfortunately the undo manager in both the MacOS X Cocoa Framework and the Java Swing Undo manager would require a bit of extra bookkeeping in order to properly set the source of a state change. However, I think the extra work may be worth it on a future project.

Keeping track of C++ templates

May 16th, 2008

So I needed to build a complex template. I wanted to build a map which also operated as a cache: as the contents of the map hit a limit on the number of objects in the map, the last referred to objects are automatically erased from the map. (What I’m doing is writing a bit of code to insert itself between a Sqlite database and some accessor code, but the pattern of access would cause a lot of unnecessary ’select’ statements. Rather than trying to load my database in memory and somehow manage the synchronization from a bunch of places, a database cache seemed to make the most sense for my application.)

I ran into two interesting things which I’m noting here for future reference.

Keep the interior value declarations simple by using the typedef keyword.

At one point I found myself writing the following code:

   std::pair<std::map<Key,std::pair<std::list<Key>::iterator, T> >, bool> ret;

And of course the code didn’t work–which was really irritating, because I was getting all sorts of weird messages that had something to do with whatever it was I was declaring. Arg!

My lesson: break the declarations into class-scoped typedef declarations:

typedef std::list<Key> CacheList;
typedef CacheList::iterator CacheIter;
typedef std::pair<CacheIter,T> MapVal;

typedef std::map<Key,MapVal> Map;
typedef Map::iterator MapIter;

Then the declaration of the return value of a std::map::insert() call becomes easy:

std::pair<MapIter,bool> ret;

Once I did this, I learned my second lesson:

Sometimes you need to declare a type as a typename for some odd reason.

I’m sure there is some C++ template expert out there who will tell me why–and it will be blindingly obvious when I hear the explanation. I’m sure it has something to do with the nature of the declarations and how they are used within a template class declaration. But for now, it seems to me that under some cases you need this ‘typename’ keyword for reasons that aren’t obvious to me–but once they’re there, all is good in the universe.

And for those experts out there, I’m sure you spotted what I screwed up in the above listing right away. For the rest of the class, I needed to insert ‘typename’ for the iterator typedefs:

typedef std::list<Key> CacheList;
typedef typename CacheList::iterator CacheIter;
typedef std::pair<CacheIter,T> MapVal;

typedef std::map<Key,MapVal> Map;
typedef typename Map::iterator MapIter;

Without the ‘typename’ declaration, I was getting these mysterious errors:

type std::list<Key, std::allocator<_CharT> >' is not derived from type 'mapcache<Key,T>'

For reference, the class that I put together to do this simple caching scheme is here. Licensed with a BSD-style license in case anyone else finds it useful.

Macintosh Programming

May 9th, 2008

One of the more interesting aspects of Macintosh programming is that you find yourself sweating the details. You find yourself spending a day or two sorting out NSViewAnimation in order to get your inspector window to open and close subsections gracefully. You find yourself worrying if “Lucidia Grande” is properly selected as the default font for a number of controls. You find yourself wandering how to create an anti-aliased box around a group of items in a tree view.

This fits very well into my theory as to the different levels of software development, and why I don’t think I want to work for a dot.com anymore.

At the bottom level are the business analyst programmers. Their job is to take data and write a program to generate a report–and in many ways this is the easiest sort of programming, since you are probably the only person who will ever run your program. The goal is not code elegance, but the report–and if you have to hack your code together in a mix of Visual Basic and SQL and a little Microsoft Excel bit fiddling, it doesn’t matter, since the product is the report.

Next comes back-end “enterprise” software development. Most of Yahoo!’s Panama system consisted of this sort of development. The audience for your software will either be analysts or internal people (such as Yahoo’s advertising editors and sales people); if a feature isn’t elegant or doesn’t quite work right, you just send out a memo warning people not to use the feature until the next version is rolled out. What makes this sort of development a pain in the neck are the number of Architecture Astronaut wannabes floating around who over-engineer aspects of the system because, well, because it doesn’t matter. (One component I worked on was broken into eight separate EJBs with elements using Hibernate–and the fellow who was nominally in charge of this code justified the design because of the “heavy load” the system would take. Nevermind it made the system impossible to debug or add features to–or the fact that at maximum load it may take perhaps 10 transactions a second, which, with a simpler design, could be handled by a modest box running MySQL…)

Next on the totem pole comes application developers who are releasing boxed software. The audience for this piece of software are end-users–and there could be thousands or millions of them: customers who just plunked down $49 or $199 or $499 or whatever, and they bloody well expect every bit to just work.

And at the top of this totem pole comes embedded developers, whose software could be used by thousands or millions of people and which must be flawless: the end-user doesn’t think he’s buying software, he’s buying a car or a television set or a video camera, and it’s not like you can send him “version 2.0″ of his BMW 3-series car to fix a bug in the ignition timing software.

What constrains each level of software development is the audience: as the audience for the software increases, the need to get it right the first time goes up, and the ability to fix bugs “on the fly” goes down. And because the need to get it right the first time goes up, the need to properly manage the project also goes up: you cannot fix managerial mistakes (because you didn’t reign in your 20-year-old architect astronaut wannabe) by just pulling an all-nighter and rolling out a new version of the software. When you’re writing application software or embedded software, you cannot just roll out a new version tomorrow to fix the broken version you rolled out today.

That’s why I don’t want to work for a dot.com anymore. Because most dot.com software development is essentially enterprise development–and because the demand to “just get it right the first time” isn’t really there, you get a lot of mismanaged projects and a lot of screwed up politics which needlessly waste a shitload of time that could be better spent elsewhere.

I’d rather sweat the details today than deal with a “production server push” at 2 in the morning to fix some detail no-one bothered to sort out because, well, it just didn’t matter…