Take the Money and Run

June 15th, 2006

The financial world for small and medium-sized Mac software vendors is going through some interesting changes. Rumors of Google’s GBuy being released on June 28 put me in the mood to expect a shake-up, and today I’ve learned that Digital River has acquired eSellerate, a very popular payment processing service for Mac developers.

Strangely, I can’t find any confirmation of the sale on the net. All I have to go by is this email note I received directly from MindVision/eSellerate, announcing the big changes and what I as an alleged customer may expect from it. Apparently Digital River is buying up companies so quickly that they don’t have time to update the web site. The press release page does contain an announcement of acquisition, but it’s for a different company. And it’s old news! That acquisition happened a full week ago!

What is an online payment processor, and why do small-timers like to use them? To accept money through the Internet these days you either have to have your own credit card merchant’s account, or else use a payment processor who deals with all the nitty-gritty of credit cards or bank transfer from your customers, and periodically sends you a check. James Duncan Davidson recently wrote about the risks of accepting online payments, where he points out that in addition to the administrative headaches, you also take responsibility for safeguarding (and potentially compromising) the user’s private credit card information.

The services provided by these companies vary, but at a minimum they all allow people of the world to give you money for your product or service. Many of the services also provide added value by automatically handling sticky issues like sales tax computation, serial number generation, annual reports, etc. eSellerate in particular has focused on adding value in the areas of integrating the sale and product activation into the application itself. These optional features allow programmers to put the ability to accept a credit card right into the application itself, and for the application to “phone home” to eSellerate with information about the computer it’s being installed on, to prevent multiple copies of the same registered application from being used at the same time.

Until today most Mac developers I know considered their options for payment processors to be PayPal, Kagi, SWREG, and eSellerate. Today those choices remain the same, but we sit in anticipation of what it means that eSellerate is owned by a juggernaut of the PC shareware registration market. I don’t really know what Digital River’s reputation is among vendors, I just know they’re big and relatively unknown on the Mac today.

In general I’m for changes and evolution in this, the “market market.” Things are pretty good for independent software vendors today, but there is much room for improvement. Hopefully the acquisition of eSellerate and the impending arrival of GBuy means we are about to enter an era of competitive innovation.

The Apple Repair Circus

June 14th, 2006

This post is part of my MacBook Pro Complaints series. Instead of (or in addition to) linking directly to this post, consider linking to the series link, which includes a summary of all findings to date and direct links to the pertinent downloads that users may find useful. Thanks for reading!

I got my MacBook Pro back last week from its second trip to Apple’s Texas repair facility. I have to admit, the turnaround was fast this time: only about 5 days from DHL pickup to DHL return. Unfortunately, the speed of the “repair” is evident in the results I have observed.

The first thing I noticed while removing the machine from its box was that a minor cosmetic defect had been added: the top surface of the MacBook Pro’s interior (the wrist-rest area to the right of the trackpad) now has a nice surgery scar. The case bulges ever so slightly here, to reveal a thin gap between the DVD-ROM slot and the top surface. Not the biggest problem in the world, but when you’re hoping for repair, it’s not fun to have it come back worse than you sent it.

Speaking of which, they did at least replace the screen inverter this time. The bad news? It seems that they replaced it with another board, defective in a different way. Is this what “consumable parts” means? My old inverter made a terrible buzzing noise at all but the highest brightness, where it was dead silent. This meant that with QuietMBP and highest-brightness, I could work in complete silence (albeit at the expense of my battery). The new inverter is noisy at all brightnesses, and is a distinctly different type of noise. While the old was more buzzing, the new is more hissing. In a way it’s better, because it’s closer to white noise. But it’s also worse and more infuriating because there is no workaround for it.

I was so disappointed that I set the MacBook Pro aside and didn’t use it for a week. I didn’t want to face the thing. I get very little joy out of using it, and it’s value has been reduced to an Intel test box that I can take with me when I travel. My PowerMac G5 is slower, but it’s comfortable. It’s like choosing between a Ferrari with no seat-back, or a Ford Escort. Sure, you can get a lot farther a lot faster in the Ferrari, but you’ll hate every minute of it.

Another infuriating aspect of Apple’s repair process is that they don’t put any comments on the repair sheet. You go to lengths to describe the numerous problems afflicting you. They write down copious notes. They agree with you that all the problems should be checked out and will be tested thoroughly. Then you get it back and they’ve replaced one part in the hopes of addressing one problem, and completely (it would appear) ignored everything else.

So my machine still whines terribly. It’s a bad problem, Apple. It’s ridiculously loud and the workaround eats my battery and probably makes the machine hotter. I want to be a PRO user. I want to work like a pro. Live like a pro. Concentrate like a pro.

And my machine still throbs with heat. The reason I’ve waited so long to update my blog is that I haven’t been willing to face the machine. I want this all to be over with. I’m only inspired to write this because I am away from home for a few days, so I “needed” to bring the portable. My hands have that residual warm throbbing that comes from being pressed against something uncomfortably warm for more than a few minutes. And this is on a relatively cool day. The heat of summer is looming like a portable-computing killer.

This is a crappy era for Apple hardware. It’s sort of a great time for Apple hardware, but the flaws make me yearn for the bad old days.

Heck, I’m even jealous of my girlfriend’s ThinkPad. Ugly and with a crap operating system, but completely silent and cool to the touch. Can I get Mac OS X with that?

Update: Sitting here with the machine on and little ambient noise, I finally figured out what the “new inverter hiss” sounds like: leaking gas! It sounds like there’s a pilot light out in my MBP and the whole room is going to blow at any moment.

Drag If You Want To

June 7th, 2006

Handling drags to your Cocoa application is pretty simple: you just have to implement the informal NSDraggingDestination protocol in some view hierarchy object that has been registered for particular drag types.

Usually a drag is handled by a specific view that can make sense of the drag’s data type. For instance, an NSTextView will accept text from the dragging clipboard and plop it down into the edited documnt. Most of the time, drags should only be handled by these specific views, but sometimes it makes sense to intercept “unhandled drags” and make something useful happen for the user. For instance, when a user drags a URL to a web browser, you might as well assume that they want to open the URL, even if they carelessly let go somewhere in the browser window’s non-descript background texture.

Apple made it easy to handle such “drags of last resort” at the window level, by kindly passing along all dragging offers from NSWindow to the window’s delegate. If your delegate simply implements the required methods, you can snag and make useful any drag that would otherwise bounce back to the originator.

But handling such non-specific drags at any level lower than NSWindow becomes tricky. There is no corresponding “delegation” when it comes to NSView, so drags that hover over or release in an uncooperative view will not be accepted, even if you’ve asked the view to register for the desired types.

When you are faced with the desire to “stake out” part of a window’s real-estate as a drag destination, the simplest way to do so is to sneak a custom NSView into the hierarchy that does accept drags. But instead of writing a custom view every time you need to do this, why don’t we follow AppKit’s lead and write our own NSView subclass that makes use of the delegation strategy.

RSDragDelegationView (MIT License) is a very simple NSView subclass that does just this. To mark the background area of a part of your UI as dragging-receptive, just select items in Interface Builder and “make subviews of custom view.” Set the class of the custom NSView to RSDragDelegationView (drag the header file to your IB document to teach it about the class), and connect the “mDraggingDelegate” outlet to the delegate instance. From your delegate code, you can now ask the custom view to register for your desired drag types, and all dragging messages will be forwarded on to you as they’re received.

An example of where I use this in my own code is in the “product registration pane.” I want to accept drags generously, because I advise users to drag their product registration email into the window after they’ve paid. If they can’t figure it out, they might email me, and while I’m always up for a nice customer chat, I’d just as soon talk about other things. There’s no reason for me not to make this as error-proof as possible, so I stake out the entire space of the tab view item in which the pane is installed. By using a custom drag-enabled view I avoid inflicting drag receptivity on the rest of the window, and keep the dragging-related code right near the controller code for the UI that needs it. If another section of the window’s UI needs to accept drags liberally, the same trick can be applied without complicating drag-handling at the window level.

Livin’ in a WordPress Hacker’s Paradise

June 5th, 2006

I have been happily using WordPress as the infrastructure for this blog since its inception, almost one year ago. Since I’m perhaps slightly geekier than than the average WordPress customer, I have been wanting to get to know the sources a bit better and possibly make my own tweaks or write plugins to suit my particular needs. I also like to keep up to date with the latest versions of the software. The problem is that these activities are at odds with each other. See, if you don’t tweak anything, updating is a simple matter of “un-tarring” the package file over your existing installation and visiting the “update.php” URL. But if you’ve made any sneaky changes, you’re liable to overwrite them when you clobber a source file with the updated version.

This situation has led me to an unfortunate state of moaning about having to install WordPress updates. This is bad, because often the small updates contain security fixes, which are exactly the kind of thing I should want to install immediately. Furthermore, I’d like to stop editing WordPress with vi on the server, and searching the source base with grep. I’m proficient with these tools, but I have a Mac! It’s better at such things.

I need absolute WordPress control. Specifically, I need to be able to:

  1. Install WordPress updates with ease and confidence.
  2. Hack on WordPress and test results on my Mac before updating the live blog.
  3. Do so in a way that meshes with my regular work habits.

How do I address this? The problem screams for Subversion and Xcode, so that’s what I will throw at it. By integrating my WordPress hacking with Apple’s Xcode, I can treat the technical underpinnings of my blog just like I would any other code project. I spend so much of my day “building and running” that it’s distracting when any technical project does not fit in with that process.

Step 1: Get Things Under Control

Source control, that is. I decided that I needed a single repository where both my live web site and local Mac could access the same WordPress sources. That means I need an SVN server accessible from both locations, as well as Subversion client tools in each location. Luckily DreamHost comes standard with Subversion support (minor gripe: they’re stuck on version 1.1!). If your web host doesn’t offer Subversion, you might be out of luck for this particular round of magic.

Typically with Subversion repositories, the “mainline” of the project is identified as a subdirectory of the repository called “trunk.” In my case, I don’t control the mainline of WordPress, so I’m choosing more clear identifications. My repository is “all branches,” if you will, so I’m not including any folder called trunk, though “official” is the closest thing to being that:

% svn ls file:///home/jalkut/svn/opensource/wordpress/          
hacking/
official/
redsweater/
redsweater-assets/

What I’ve done here is take advantage of the “smart copying” in Subversion. I started the repository out with “official,” containing the latest 2.0.3 release of WordPress. I then copied that in the repository to “redsweater” and carefully copied all of custom bits and pieces in. If you do this right, only the customized parts take up repository disk space. Everything that’s the same is shared in the database. The custom bits include the database configuration, custom themes, installed plugins, images, etc.

Where possible, I took advantage of a feature in Subversion called “svn:externals.” This lets you specify points in the project hierarchy that, when encountered, will trigger a checkout from a different repository. It’s sort of like an NFS Mount-Point right in Subversion. In the mysterious “redsweater-assets” repository folder above, I’ve added folders for most of my custom elements. So when I checkout “redsweater” and Subversion gets down to the “themes” section, it notices that it needs to checkout my custom theme from the redswetaer-assets/themes repository folder. This technique works great in almost every area of WordPress, except for the plugins directory. Because svn:externals can only specify a directory, it breaks down when one would hope to use it to plop individual files down into a checked out directory. I imagine this limitation comes from the fact that every folder in a working directory has a single “.svn” folder for tracking the entries at that level. Therefore, a directory of assets from mixed repositories would be tricky.

Even with the svn:externals shortcomings, the setup works pretty well now. I have a “redsweater” branch that I can integrate changes into, and then update my web site directly from the command line. At any time, I can examine the differences between my customized branch of WordPress and the official release I last integrated with. Comfort!

Step 2: Integrate with Xcode

The Subversion infrastructure goes a long way toward calming my nerves about integration and updates. I can carefully stage any update by first updating and testing it on my local machine. That’s cool, but it’s not really good enough. I want to be able to hack the heck out of it on my local machine (Note: You need to install a PHP-compatible Apache server before you can really do this on your Mac). Furthermore, I want to possibly be able to maintain a separate, highly experimental copy of WordPress for days, weeks, or months while I continue to serve (and perhaps update) the more stable version of the blog from my site. It’s time to look at the “hacking” branch that I hinted at above.

The hacking branch started life as a copy of the redsweater branch. I want it to closely mimic my real blog, but I want to have freedom to mess around with it big time. So the first thing I altered after copying the branch over was the wp-config.php. Instead of pointing to my live database, I pointed to a local MySQL database on my Mac (yet another custom install, sorry!). This database contains a subset of my live blog’s content. The idea is it’s a totally safe sandbox for me to work in. I can add comments, posts, pages, etc. I can delete everything and start from scratch. I can even post drafts of my entries from MarsEdit to see how they’ll really look when they finally go live. The ultimate preview! One of the things I’ve noticed so far in hacking on WordPress is that I need to provoke different situations before I can play around with the behavior. For instance, if I want to tweak the spam-filtering behavior, I have to first cause a spammy comment to appear on the blog. I don’t like doing this on the live blog, but fake spam comments are fine in my sandbox.

What else does the hacking branch contain? This is where it gets fun. The branch contains an Xcode project file, and supporting shell scripts to facilitate a streamlined development process. First I added all the WordPress sources to the project, for easy global search & replace. It’s amazing how much faster you can get to know the project when you get a “birds-eye view” from Xcode:

I find that I understand a project much better even by doing simple tweaks like globally replacing something so that it behaves differently. When I can observe the changes, it connects my test changes to the project’s design as a whole.

Next up I attacked the problem of “fixing the workflow.” What does it mean to “build & run” a WordPress project in Xcode? I decided that building WordPress means “copying the files into my local web server directory,” and running it means “opening a suitable URL in my web browser.” To that end, I added a single target to the Xcode project, “Install Local,” which is a simple copy files build phase target. It takes all the specified files and plops them over to the “blog” subdirectory of my local test server:

Sweet! Now when I want to try out my changes, I can just press Cmd-B to build and then load up my localhost URL in Safari. But the scenario isn’t quite complete. When I build an application in Xcode, I don’t have to navigate to the Finder, find the resulting product, and double-click it. Why should I have to go manually reload this web page? With Xcode custom executables, I don’t. I added a couple shell scripts to my “hacking” tree that, when specified as custom executables, simply cause the local blog to open up in the default browser. This trick is accomplished with some simple AppleScript bridging:

#!/bin/sh
osascript -e "open location \"http://localhost/blog/\""

For every commonly debugged location in the blog, you can just pop another custom executable into the project with a slightly different blog URL. Then you select the desired executable from Xcode and “run” the project to see how your results are shaping up.

Now I can make changes, build, run, examine the results, and even use Xcode’s built-in Subversion features to review what I’ve changed!

If you want a head start at making your own WordPress hacker’s paradise, you can download and plop my WordPress Xcode Project files into your own local WordPress “hacking” directory. It should work just fine with a standard 2.0.3 copy of the sources. The archive includes the Xcode project itself as well as a couple example “executable” scripts.