Leopard Isn’t The Problem

April 12th, 2007

Apple announced yesterday that Mac OS X 10.5, code/marketing-named “Leopard,” will not ship in Spring as promised, but will instead ship in October. (Confoundingly, the “Hot News” item at Apple doesn’t even have its own link, naked among the other public relations tidbits. Perhaps a sign that they’re not proud of the statement).

The announcement caps off a season of speculation alleging fluctuations in Leopard’s ship date. While early 2007 brought us lunatics predicting a March release, more recent speculation has hinted that a substantial delay was inevitable. This theory was soundly rejected by Apple less than three weeks ago, in a response to what turned out to be quite an accurate preview of the brutal truth.

The news has inspired reactions by respected Mac OS X developers (Gus Mueller, Brent Simmons, David Weiss, among others) and users (David Chartier, John Gruber, the Macalope, and many, many others). But while these people offer intelligent views on the relative pros and cons of the delay and its consequences to ordinary people, I don’t see much reaction to the core problems in Apple’s confession. I envision a bunch of PR folks sitting in an office toiling with the fact that they’ll have to break this unfortunate news. What to do, what to do. One of them has the brilliant idea that they can simply “blame” the iPhone. By blaming a problem on what’s widely perceived by the public to as a success, it will somehow make the company appear mature and well-reasoned in its decisions. Something more excusable than a company that occasionally fails to work a miracle. And somehow this idea made its way through some review process and all the way to public release. In stark contrast to Steve Jobs’s brilliantly candid Thoughts On Music, this statement sounds made-up and poorly thought-out. Bluntly crafted, sleazy marketing bullshit.

The best we can hope for is that it is only sleazy marketing bullshit. Because if what Apple’s telling us is true, then they’ve confessed something tragic: they’re incapable of building more than one amazing product at a time. The iPhone looks like it will be an amazing product, but if Apple can’t keep an OS team focused and operational at the same time as they keep a cell phone team hacking away, then the company is destined for extremely rough waters as it attempts to expand the scope of its product line.

What happens when the phone takes off, and Apple’s stuck following through on their Mac OS X commitments? “Sorry, no iPhone 2.0 until 2009 – we’ve had to move everybody back to OS X!” Needless to say, even with the apparent comingling of iPhone and iPod technologies, this situation leaves me unable to speculate as to when a dramatically new iPod might find time to be developed in this environment.

If Apple is truly so strapped for talent that they can’t focus on more than one product at once, then it’s a symptom of a sickness within the company. Perhaps they’ve regained success too quickly. If a company with a market capitalization of $80 Billion, and a cash account of at least $6 Billion, cannot hire enough people to build three of the hottest, most demanded products in consumer electronics (the iPod, the Mac, and the iPhone, if it’s not obvious), then maybe it’s time to reevaluate their modus operandi for attracting and retaining talent.

The first thing Apple should do is go global. Their products are universally renowned, yet the company requires the vast majority of its engineering teams to live and work in California – in a suburban, high-cost area of California, at that. Sure, Apple has a few small teams scattered around the world, but mostly as side-effects of specific acquisitions. The message to all Mac developers I know is being heard loud and clear: if you want to be part of this revolution, you’ll have to move to Cupertino. By limiting the company’s ranks primarily to those people willing to live in this one particular geographical location, they shut down their ability to attract a huge number of talented individuals.

If Apple’s having trouble growing its ranks of geniuses, the solution may require something that no amount of cash or stock can buy: a change of attitude.

Abusing Objective C With Class

April 12th, 2007

Dynamic messaging is one of the nifty features of Cocoa and Objective-C programming on the Mac. You don’t have to know which class, or even which method your code will call until runtime. The feature is utilized a great deal by the delegation pattern employed by most standard classes in AppKit. For instance, when a window is threatening to close, Apple yields the final decision making to a delegate method, if present:


- (BOOL) windowShouldClose:(id)sender;

If you implement this delegate method and return NO for a particular window, then the user’s attempts to close it are thwarted (hopefully because you just did something friendly like ask them if they were sure or not).

If we’re agreed that delegation and dynamic messaging are a good idea, we should be prepared to use them in our own code as well. Let’s say we’re writing a custom class where delegation of this kind would be useful. We’d like to be as much like Apple as possible, to further solidify the patterns that we all use on a regular basis.

My example application is a coffee maker, and it makes coffee at regular intervals unless the delegate method believes it should not:


- (BOOL) coffeeMaker:(RSCoffeeMaker*)theMaker
	shouldBrewForScheduledDate:(NSDate*)scheduledDate;

What must the code in the coffee maker do in order to satisfy this contract? The “scheduledBrewTimerFired:” method might look something like this:


- (void) scheduledBrewTimerFired:(NSTimer*)brewTimer
{
	BOOL shouldBrew = YES;
	
	// Give the delegate a chance to reject
	SEL delSelector = 
		@selector(coffeeMaker:shouldBrewForScheduledDate:);

	if ((mDelegate != nil) &&
		([mDelegate respondsToSelector:delSelector] == YES))
	{
		shouldBrew = [mDelegate performSelector:delSelector
			withObject:self
			withObject:[brewTimer fireDate]];
	}
	
	if (shouldBrew == YES)
	{
		//...
	}
}

Nifty, right? Yes, nifty. But wrong. What’s the problem? It’s that line where performSelector is called. If you have as many warnings turned on as you should, you’ll see something along the lines of “warning: assignment makes integer from pointer without a cast.” The reason? The performSelector method returns an “id”, not a “BOOL”. We’re expecting magic to happen here, and those of us who grew comfortable with the nuances of PowerPC-based calling conventions have seen magic happen here more often than is healthy.

By violating the function prototype for performSelector, we’re robbing the compiler of its ability to accurately produce assembly code that retrieves the BOOL return type correctly. That means we’ll get the wrong answer some percentage of the time, where that percentage is determined by the degree to which BOOL and id return types are handled differently on the platform.

My first instinct in addressing this problem was to go down a layer. Surely if performSelector is using an unsatisfactory prototype, I could just drop down to objc_msgSend and handle the messaging myself. But alas! The lower-level function also returns an id. At this level, there are some special functions such as objc_msgSend_stret, which messages an object and returns a structure, but there isn’t a handy objc_msgSend_boolret for our convenience.

So what’s a conscientous developer to do? I was lucky to discover a mailing-list thread, in which the answer to this question was beautifully outlined by Greg Parker of Apple. Credit also goes to Rosyna of Unsanity, for asking the question that led to Greg’s answer. Rosyna later expressed appreciation in a follow-up post.

So what’s the trick? In order to get the freedom of dynamic messaging combined with the complete cooperation of the compiler, we need to define a custom function pointer. This points to the same address in memory as the objc_msgSend function, but is defined with a differing prototype. This way we get the message delivery functionality of the Objective-C runtime, while letting the compiler in on the fact that the method being messaged will in fact return a BOOL typed response.


#import <objc/objc-runtime.h>

- (void) scheduledBrewTimerFired:(NSTimer*)brewTimer
{
	bool shouldBrew = YES;
	
	// Give the delegate a chance to reject
	SEL delSelector = 
		@selector(coffeeMaker:shouldBrewForScheduledDate:);
	if ((mDelegate != nil) &&
		([mDelegate respondsToSelector:delSelector] == YES))
	{
		// Give the compiler a clue - courtesy of Greg Parker
		BOOL (*MyMagicSender)(id, SEL, id, id) = 
			(BOOL (*)(id, SEL, id, id)) objc_msgSend;

		shouldBrew = MyMagicSender(mDelegate, delSelector,
			self, [brewTimer fireDate]);
	}
	
	if (shouldBrew == YES)
	{
		//...
	}
}

Nifty, right? And correct, too. Enjoy!

Update: Paul Kim via chat, and Jan Van Boghout in the comments below each noticed a flaw in my contrived example. Since I already know the selector I’m planning to call, I could just define it explicitly with a regular Objective-C method prototype. Then the compiler would know exactly how to generate the code if I called the delegate directly:


shouldBrew = [mDelegate coffeeMaker:self
	shouldBrewForScheduledDate:[brewTimer fireDate]];

That’s true, and it’s a fault in my overly-contrived example. But imagine a more dynamic scenario, where the prototype of the method is known, but not the selector. For instance, if the class offers clients the ability to specify a selector:


- (void) scheduleBrewingAtDate:(NSDate*)brewDate
	withBrewDelegate:(id)brewDelegate
	withDelegateSelector:(SEL)delSel;

Are You Feeling Lucky, Punk?

April 11th, 2007

In the years since I first started developing FastScripts, all manner of keyboard-shortcut type solutions have popped up, including the enormously ambitious Quicksilver, and the refined, trigger-action-oriented Butler.

But some of us still appreciate FastScripts for its simplicity. Put scripts in the standard Apple-location, cmd-select them from the FastScripts menu, and assign a keystroke. FastScripts could be improved in some important ways, but it’s been in “stable and revered” mode for years now, which has made it a reliable tool for people to recommend to others. I think it’s easy to recommend because it does exactly what it says it will do, and little more. You don’t need to join a FastScripts cult or change your entire workflow to get some use out of it!

Michael Tsai recommends it in the manual to his BBAutoComplete product. I see frequent referrals from Quark and InDesign forums, where running scripts efficiently is a major part of the creative and production process. It’s gratifying to know that FastScripts has become a part of the productive environment for so many people.

But sometimes people just use it because they feel lucky. Christopher Biagini shares his I’m Feeling Lucky script, which performs a simple but useful task. It asks you for a phrase, then it does the Google search for you, then it takes you straight to the “I’m Feeling Lucky” link. I clicked the handy “open it directly” button which worked like a charm to bring it to Script Editor. Then saved it to my Scripts folder and assigned a keystroke. Nifty! And a lot lighter-weight than Google Desktop :)

Go ahead, make my day. Give FastScripts a try!

Future Posting With MarsEdit

April 9th, 2007

From time to time people ask for a feature in MarsEdit that would allow scheduling of posts for future publication. While I can appreciate the desire for such functionality, the drawbacks to implementing it on the client-side are numerous. To schedule a future post, MarsEdit or a custom tool from MarsEdit needs to run in the future, at a precise time specified by the user.

Launchd and other system scheduling services make this task less formidable, but it’s still not exactly something I can whip up overnight. Fortunately, some publishing systems treat posts with future dates as unpublished, and automatically change their state to published when the specified date arrives. WordPress in particular definitely supports this. To see if your blog supports it, next time you’re publishing a post try setting the date to just a few minutes in the future. From the Post menu, select “Edit Date,” and enter a future time:

I am writing about this because I suspect many people don’t know about this really cool feature. I didn’t know about it myself until very recently. I was motivated to research it when Guy Kawasaki asked about the possibility. He confirmed that the trick works with his (excellent) TypePad-based blog, too. [Update: I believe the TypePad functionality may have only appeared to work. I have since learned that TypePad doesn’t seem to support this the way we had hoped.]

For any WordPress users who are curious, the functionality in that system is based on a nifty general-purpose “cron-like” service built-in to WordPress 2.1 and later. This allows the system and plugins to schedule future actions for a variety of purposes, including future posting. Glenn Slaven has a nice article about the WordPress scheduling technology.

Aside from WordPress and TypePad, I have confirmed this also works in Google Blogger. I’m not sure which other systems suport future-posting in this way.

Please let us know in the comments if you discover the feature works as expected on your blogging system of choice.