Spittle Over Frozen Carbonite

Saturday, 2006-10-07; 01:09:00


Why Shipley's argument regarding the ease of using Carbon frameworks is spot on.

Gah. Wil Shipley posts about the difficulty of creating apps using Carbon frameworks versus using Cocoa frameworks. His argument (to quote him in the comments) is "Carbon is based on an older metaphor of programming and is inherently flawed in my view because of it." And from my personal experience with the occasional Carbon framework, his overriding argument is entirely correct.

There are two "Carbon" frameworks with which I've had to deal with: Authentication Services and QuickTime. Both are a bitch to use (at least before QTKit in 10.4). With Authentication Services, I had to go through a whole bunch of rigamarole, creating AuthorizationRights structures, creating AuthorizationFlags structures, passing pointers to other AuthorizationRights structures, freeing the AuthorizationRights structures later, etc., etc. You even have to do ridiculously superfluous things like figuring out the string length of the path to the command line tool to which you want privileged access, even though the framework should handle that by itself if it needs to know that information. Here's the requisite code in Memory Usage Getter that simply authenticates the user:

- (BOOL)auth
{
    AuthorizationRights theRights;
    AuthorizationRights *authedRights;
    AuthorizationFlags flags;
    AuthorizationItem items[1];
    char killToolPath[] = "/bin/kill";
    OSStatus err = 0;
    BOOL isAuthorized = NO;

    items[0].name = kAuthorizationRightExecute;
    items[0].value = killToolPath;
    items[0].valueLength = strlen(killToolPath);
    items[0].flags = 0;
    theRights.count = 1;
    theRights.items = items;
    flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights;

    err = AuthorizationCopyRights(authRef,&theRights,kAuthorizationEmptyEnvironment,
                                  flags,&authedRights);
    isAuthorized = (errAuthorizationSuccess == err);
    if (isAuthorized) {
        // update the user interface, some code removed here        
    }

    return isAuthorized;
}


It's not pretty. If there were a Cocoa wrapper around Authentication Services, I should be able to do this:

- (BOOL)auth
{
        NSDictionary *errorDict;
        BOOL authSucceeded = [[NSAuthenticationServices sharedManager] authenticateTool:@"/bin/kill"
                                                                        withErrorDict:&errorDict];
        return authSucceeded;
}


[UPDATE: I originally posted a more extended snippet of code from MUG, but it turns out that a lot of it was duplicated unnecessarily. I was following the examples in Apple's documentation, though. I guess I accidentally used more code than was needed.]

Note that I've even included error handling. The error dict can provide whatever information is needed for the developer to diagnose the problem. (Indeed, NSAppleScript objects do error handling in exactly this way.) If the developer is a good Mac developer, he'll expose the errors to the user through pretty dialogs that include human-readable error messages, ones that are passed to the app via the errorDict from the hypothetical AuthenticationServices framework.

The Carbon code is ridiculously complicated and unnecessary and is another perfect example of Shipley's argument. I was pretty much following the Apple-provided examples exactly in order to get this to work, and it took me a few days to finally get it right. I had to create a whole entire new class for MUG when all of this stuff should've been inline with my other classes.

It's mind-boggling how complicated it is, especially to a programmer like me who started Mac programming with Cocoa. And I can easily see why Shipley goes off on a rant.

What pisses me off, though, is when people like Rosyna (in the comments) or Matt Simpson or Erik Barzeski get their panties in a bunch simply because they can't ignore some of the more minor errors in the argument. Yes, FSRefs are better than using file paths because moving the file in the Finder won't cause the app to save the new file in the original location. Yes, Cocoa actually is older than Carbon, but that's irrelevant to the argument. Yes, Shipley might have muddied the definition of "Carbon" and "Cocoa", but in reality they're not exactly clear-cut to begin with.

Have these guys never tried to use the Carbon frameworks in question?

Nothing against Rosyna or Simpson or Barzeski. I've linked to them in the past and they often make good arguments, and they're certainly knowledgeable on the subject. So why can't they get past the errors and realize that Shipley is -- on the whole -- correct?

Shipley does a bit of chest-thumping when he boasts about how much money he's made off of Delicious Monster, blah blah blah. But even there, he makes a good point, because he had to make a decision on when to ship Delicious Library, and he decided to favor features and interface over the speed of the app. Delicious Library 1.0 was supposedly pretty damn slow when having hundreds of items in the library. But Shipley decided that shipping the app was more important than having it run fast.

Have Rosyna and Barzeski forgotten Mac OS X 10.0? Shipley made the same exact decision that Apple did: ship first, optimize later. It's a completely valid choice, and usually in many cases, the more correct one, especially when dealing with larger apps that will take time to optimize. Had Apple waited for Mac OS X to get to the level of 10.0 before releasing it to the public, there wouldn't have been any of the app support until years later. Remember, Microsoft Office X came out for 10.1.x. There was little support for 10.0.x from any of the major Mac developers.

Simpson points out that comparing Delicious Library to Mac OS X is not a valid comparison, because Delicious Library has no legions of developers waiting for it to ship. But that doesn't matter. Apple made the same decision with iPhoto 1.0. Apple made the same decision with iMovie 3.0 (which was the first version to be developed in Cocoa). Both of these apps had the same speed problems that Delicious Library 1.0 did, and yet they were still shipped!

Simpson is "irked" by Shipley choosing to ship his app knowing that there were speed problems. That smacks of presumptuousness on Simpson's part! (For what it's worth, Simpson acknowledges this.) A valid reason to do what Shipley did is if he needed funding to continue the project. He may not have had any other source of income, and so taking 7 months to develop version 1.0 was already pushing it. Had 1.0 not been released, it's possible that he wouldn't have been able to pay rent, utilities, etc., etc. I don't know if this is the case, but there's at least one valid reason to ship a slow product.

Again, Rosyna and Barzeski and Simpson seem to get irked because Shipley has an ego or he oversimplified the difference between Carbon and Cocoa. But Shipley's overall argument is spot on.


Technological Supernova   Rants   Older   Newer   Post a Comment