Code by Kevin

Code by Kevin, Programming, code, business, and other pursuits

Your Host
Kevin Walzer, software developer.


Subscribe to RSS Feed
Get a syndicated feed of my weblog.



Privacy Policy

Site design: Skeleton


Mon, 20 Dec 2010

2010 in review

Like many other Mac developers, each December I try to take a look back at the past year, and look ahead to the coming year. Here are some of the highlights:

Sales. Sales this year are on pace to finish about 15% higher than 2010. The main reason for this is greater success with promotions, specifically my participation in daily promotional offers at MacZot and in a software bundle sponsored by MacBundlePro. These promotions, while yielding only a small amount of revenue per sale, brought in so many new users for my program that the boost to my bottom line was substantial. I know there is some disagreement among developers about the value of these types of promotions, but in my case there's no doubt--they are a big plus. I'll be continuing to look for promotional opportunities in the coming year, as well.

Improving the integration of my apps via custom libraries/extensions. If you've followed this blog at all, you know I've spent a lot of time this year working on custom Tcl libraries to access specific parts of the Cocoa/Mac API's: drag-and-drop, AppleScript/Apple Events, printing, icon display and manipulation, services, unified toolbar, and more. This has dramatically improved the user experience offered by my programs. The drawback, however, is that I have invested less effort in adding new features to my applications, nor have I developed any new products for my portfolio. Now that my software platform has more robust integration with OS X, in the coming year I plan to spend much more time on improving and adding application-specific features--and, finally, developing new applications.

The Mac App Store. This change, announced in October, is very exciting: it offers the opportunity for a much larger audience for Mac programs, offering ease of searching and installation. I'm going to add most of my applications to the App Store, and development of new apps will be done with the App Store in mind. I'm hoping that this leads to a significant increase in sales for my products. Needless to say, I'm excited.

Thanks for your support in 2010 and I'm looking forward to 2011!

[/business] permanent link

Moving ahead on App Store

Apple's announced that the Mac App Store will be open for business on January 6, 2011, and have given developers a deadline of December 31 to submit their apps for inclusion on opening day. I'm busy getting a couple of applications ready to submit, and I hope to see them included for sale on January 6.

I know I've been going back and forth on how, or even whether, to integrate the Mac App Store into my software business. I've arrived at what I think will be the best strategy for my customers and myself. What I've decided to do is to maintain two sales channels for my software: the Mac App Store for the majority of my programs, and my own website for all of my programs, including ones in the App Store and ones that wouldn't qualify.

This approach means more work on my part, because I will have to maintain two builds of my software, one for the App Store and one for outside the App Store. I've had to make some significant changes in how my programs are built and structured internally as a result of this. But this approach is the best one for my customers. One, it will allow anyone to download demo programs of my software from my website; demo versions aren't allowed in the App Store. It will also allow those customers who do not want to purchase from the App Store to purchase from my site directly. Finally, it will provide continued upgrade support for my existing customers, who otherwise might have to re-purchase my products from the App Store.

Apart from the work on maintaining two separate builds of my products, the App Store is also driving actual improvements to my apps themselves. Under the hood, I've replaced many functions that previously called to built-in command-line tools on the Mac with native implementations. For instance, instead of calling to the command-line "osascript" tool to run AppleScripts, I use a Tcl library that accesses AppleScript directly (one of the libraries I worked to update earlier this year). This is both faster than executing the command-line tool, and more stable; it appears to avoid the conflicts with third-party AppleScript extensions that have caused frequent crashes in some of my programs. I'm also calling into native API's to play alerts, check to see if certain programs are active, and more. In addition to speed and stability for certain functions, I'm also improving the UI of my apps by implementing a true "unified toolbar" appearance; I've submitted a patch to the core Tcl/Tk developers to make this functionality available to other Tk developers.

The App Store represents an exciting opportunity, and I hope to see my apps listed there for sale starting on January 6. I'm working hard toward that end.

[/business] permanent link

Wed, 24 Nov 2010

Adding AppleScript support to my apps

One ongoing project for me in improving the integration of my programs with OS X is by adding or enhancing their AppleScript support.

AppleScript is a programming language that allows extensive inter-application communication on the Mac, and also allows communication between applications and the operating system. Apps that support AppleScript make specific functions available to a scripting interface, and the scripting language can both drive those applications and connect them into larger workflows. For instance, AppleScript is widely used in the printing and publishing industry to automate publishing workflows. A publishing-industry AppleScript might extract data from a FileMaker database, format the same data in Microsoft Word, and then push the data into Adobe InDesign for page layout. Other major applications on the Mac with extensive AppleScript support include Safari, Mail and iTunes.

Adding AppleScript support to my own programs is not just about improving their integration into the OS, however--it's about making them more useful, and allowing them to provide data and services in ways that perhaps I don't foresee. It's about making the programs better.

There's a reason not every program supports AppleScript, however--adding it is not a simple process. It involves several steps:

  • Deciding what data and functionality to make available.

  • Adding the appropriate system-level code to define the scripting commands that will make that data and functionality available.

  • Coding the application's internal functions to expose that data to scripting commands.

  • Testing, testing, and more testing.

  • Let's look at these in more detail. I'm going to base this discussion on the AppleScript support I'm currently adding to NameFind, my file search tool.

    Deciding what data and functionality to make available. What data is most important to the application, and what functions exist to access and manipulate this data? This question will vary, depending on the application. NameFind's main functionality is to search for files in specific directories by file name. I decided to create scripting functions that allow users to set or obtain the name of the search query, set or obtain the name of the search directory, run the search, retrieve the search data, and retrieve the name of a currently-selected file in NameFind's main window. NameFind does a few other things, such as displaying detailed information about selected files and displaying QuickLook previews of selected files, but these are secondary functions that would not be very useful from a scripting interface.

    Adding the appropriate system-level code to define the scripting commands that will make that data and functionality available. There are several steps to this process. Adding AppleScript support actually means adding support for Apple Events, which is the system-level mechanism by which applications on OS X communicate with each other. To support Apple Events, a programmer has to create a sequence of four-letter codes that represent an event class (basically, the application supporting that Apple Event) and event ID (the specific event, or command, defined by that application) and register those with the operating system. Developers register Apple Event support in several different places: in the application's property list file, which the operating system parses to display the name, version, and other aspects of the program, including AppleScript support; in the application's scripting definition (SDEF) file, which maps specific AppleScript commands to specific Apple Events; and internally, in the application's code, where the application registers its internal functions that respond to Apple Events. Cocoa programmers have an entire framework called Cocoa scripting that not only allow allows them to register AppleScript commands, but specific data objects and properties from their application that can be accessed and manipulated via AppleScript. I am using different methods from the lower-level Apple Event Manager framework, accessed via scripting libraries (tclAE for the Tcl programming language and appscript for the Python programming language); these libraries easily implement AppleScript commands but have more limited support for AppleScript data objects and properties. In the case of NameFind, I added an AppleScript identifier to its property list file; created a scripting definition file that contained Apple Events and AppleScript commands to set and obtain search terms, search directories, search data, and a selected file; and added code to register the internal functions that would respond to those Apple Events, via the tclAE library.

    Coding the application's internal functions to expose that data to scripting commands. Usually functions within the application already exist for accessing and manipulating the data in question, but it is often necessary to add additional code that provides the integration between Apple Events and the application. This is true of NameFind: in part because of the way the tclAE library integrates with Apple Events, I added several procedures to access and manipulate data from NameFind.

    Testing, testing, testing. This is the most time-consuming part of the process. Once you understand the basics of Apple Events--their format, how to refer to them in your code and in other files like the scripting definition file, and how to integrate them with your own application's code--they are fairly straightforward to implement. Or so you might think. AppleScript is a quirky, sometimes opaque language. The biggest drawback to AppleScript and Apple Events is that they sometimes behave in unpredictable ways, and often do not provide useful feedback to the programmer if errors occur--which can be very frustrating. For instance, when I was testing one of the AppleScript commands for NameFind's AppleScript support, I kept getting "missing value" instead of the data that I was requesting, with no specific mention of where the error was occurring. Also, after I encountered this "missing value" error, commands that previously worked would also mysteriously fail with "missing value" errors. It took many hours of digging to untangle these problems, which were twofold: first, there was a typo in the scripting definition file that prevented the Apple Event from being recognized; and second, AppleScript caches the output of its commands for increased speed, and apparently "missing value" errors can corrupt other data that has been cached. In encountering these problems, I ran into an issue that many, many developers complain about in regards to AppleScript: more than most scripting languages, it is especially prone to subtle or even silent bugs that are difficult to reproduce and/or track down. Many issues can cause such bugs, such as the typo in the scripting definition file; conflicts between core AppleScript and one of the numerous AppleScript extensions that can be installed to expand its capabilities, or conflicts between an application command and an AppleScript core command; and other issues. I think I've gotten the bugs worked out of my implementation of AppleScript in NameFind; once the program runs all of its AppleScript commands correctly, I'll consider AppleScript support complete.

    It would actually be possible for me to implement some AppleScript support in NameFind without going through all of this extra work: out of the box, Tcl/Tk (the framework that NameFind is developed with) supports a "do script" AppleScript command, which allows the program to run arbitrary Tcl code: the AppleScript would say "do script" and then pass along some Tcl code to execute. This is actually how most Mac programs that use Tcl support AppleScript: for instance, the AlphaX text editor and the aMSN messaging program. This option has a lot of appeal. First, it would require much less work on my part, and would open up a lot more power, as Tcl is both a more powerful programming language than AppleScript and is much more transparent in reporting errors. However, this method of supporting AppleScript is also a security risk, as it would allow the execution of any Tcl code. This method also requires knowledge of Tcl on the user's part; while many Mac users might be able to do basic things with AppleScript, that is not true with Tcl. Additionally, I would not be able to use this approach with my Python programs, as Python does not have comparable support for arbitrary execution of Python code via AppleScript (for security purposes).

    Finally, it is worth it for me to implement a complete AppleScript interface for NameFind and my other programs because AppleScript and Apple Events are the standard mechanism for inter-application communication on the Mac. More Mac users are familiar with this approach than any alternative, and the AppleScript/Apple Event mechanism can also be accessed from other programming languages, including Python, Ruby, Objective-C, and the command-line shell. By going this extra mile, I'm able to make my programs much more useful and better citizens on OS X. That's an excellent reason to do this work, and so I'm doing it.

    [/software] permanent link

    Still mulling App Store strategy

    I'm still reviewing the best way to integrate the Mac App Store into my software business, and as part of that process, I've sent my customers an e-mail soliciting their input. (A copy of this message inadvertantly reached the MacNN news site.)

    I have since received dozens of responses from my customers, which is both overwhelming and gratifying, and here's what they are telling me:

  • They are strongly against making the app store the only distribution channel for Mac software. They want multiple channels.

  • They are strongly against doing away with "try before you buy." They are not likely to spend more than a few bucks on an app without trying it--the risk is just too high.

  • They are unhappy with the lack of an obvious upgrade path from existing apps (i.e. using a serial number to buying through the App Store).

  • This feedback is helpful to me for three reasons.

    First, it suggests that the lack of an easy migration path to the Mac App Store presents significant issues for my existing customer base. My customers have bought my software using traditional shareware model: download a demo, try it out, and purchase a serial number to use the software permanently. Moving all of my existing products to the Mac App Store would require my existing customers to pay full price for future versions of my products--something that, naturally, many of them are reluctant to do.

    Second, it suggests that continuing to offer a sale channel outside the Mac App Store is not only a viable option but a necessary one. Many of my customers, for philosophical reasons, do not want to purchase software through the App Store, or at least do not want it to be the only option. Also, as I've noted before, not every product--including several of mine--is going to be suitable for the App Store because it runs afoul of one guideline or another, and changing the app to meet the guideline in question is not a viable option.

    Third, it helps to provide me a road map for the development of future products. My existing customers tend to be power users or even software developers themselves, who are comfortable with searching for, downloading, and testing software from a variety of sources. The Mac App Store is aimed at a broader audience, one that does not customariliy purchase much software. Currently all of my programs, even the ones that qualify for the App Store, are geared for power users. Going forward, it might make some sense for me to develop a different kind of software for the App Store audience.

    The App Store clearly represents a huge opportunity for Mac software developers, but that opportunity needs to be balanced with meeting the needs of my existing customers--the ones who have been with me this long. While I have not yet finalized my App Store strategy, clearly that strategy must consider both existing and potential new customers through the App Store.

    [/business] permanent link

    Mon, 15 Nov 2010

    After further consideration

    I've given the Mac App Store more thought, and I've decided that the potential benefits outweigh the risks.

    It's possible that some of my programs won't be approved, but then again, it's possible that they might. I won't know unless I try. If they're rejected, then I can just sell them as I do now--outside the App Store.

    So now begins the very long process of updating my apps to meet the app store guidelines. I see this as a beneficial process, regardless of what happens with specific apps, because this process is forcing me to take a very hard look at my apps and find opportunities for improvement. There's no lack there.

    [/business] permanent link

    Thu, 04 Nov 2010

    No App Store for me

    I've come to a decision: no App Store for me at this time.

    I've reviewed the guidelines more closely, and I'm concerned that several of my apps run afoul of these guidelines.


    These three applications are 50% of my product portfolio, and they are my best-selling programs. I have not gotten rich developing them, but all three programs have steady sales and a growing customer base that benefits from the functionality these programs offer. It makes no sense to remove core features from these programs to allow them to fit in with the App Store.

    The guidelines wouldn't prevent me from submitting my other apps, but I'm also concerned about the complexity of managing two entirely separate tracks for my products: not just different sales and marketing channels, but also different development tracks. (Products in the App Store can't have serial numbers, must be packaged in a different fashion, and must be "digitally signed"--all of which would require significant changes in my development process without adding any new features.)

    The introduction of the App Store has also caused me to analyze who my customers are, and whether they fit the profile of likely App Store customers. After some consideration, I don't think they do. Marco Arment has posted a perceptive analysis of likely App Store customers: casual purchasers looking for entertainment as much as utility from their apps. In short, the type of customer who buys apps for the iPhone and iPad. Marco also suggests that the App Store will lead to the emergence of a new breed of lightweight, low-cost Mac apps--games and simple utilities--that fit in more with the iOS model than the current Mac model.

    Many current Mac apps can fit into this new market with minimal work, but many can't. Marco suggests that this isn't bad news, however; he sees the App Store as a parallel app marketplace to the current Mac app marketplace, one that will eventually grow much larger than the current Mac app marketplace, but won't destroy the current marketplace. (In fact, he says that the App Store will likely grow the current Mac app market as well, simply by sheer momentum.)

    If he's right, then I'm not too worried, and I'm even optimistic. I'm not terribly interested in making bite-sized, iOS-styled apps, but if the Mac market itself continues to grow, then that means additional customers for my nichey, power-user-oriented apps as well. I suspect other Mac developers, including such prominent ones as Rogue Amoeba, may follow arrive at this conclusion as well.

    If that's the case, then I'm in good company.

    [/business] permanent link

    Sat, 23 Oct 2010

    Thoughts on the App Store

    So Apple is bringing its iOS app store mode model to OS X. Apple approves all submissions to the store, handles all sales and billing, and takes a 30% cut. The major difference between the Mac App Store and iOS App Store is that the Mac App Store won't be the only game in town--developers are not required to sell their products through Apple for them to be installed and run on the Mac.

    I'll say this for Apple: they don't sit still. It seems that every couple of years they bring out another disruptive change that profoundly alters the landscape for Mac developers. In 2005 it was the transition from PPC to Intel. In 2007 it was the deprecation of the Carbon frameworks. And now this year, it's the Mac App Store.

    I'm still pondering the implications of the App Store model for my own products. After looking at the App Store guidelines, I don't see anything that would make it impossible for my programs to be included (like using Java as the programming language). I'm very glad that Tk now has a Cocoa foundation, as a Carbon foundation might be considered a "deprecated technology" as well. On the other hand, my apps would certainly require some tweaking to be included. I don't see this as insurmountable, but it certainly would require some work.

    The larger concern for me is the 30% cut Apple takes, and the downward pressure on prices that the iOS store has placed. While I don't see Mac programs racing toward the 99 cent price point, I do wonder if $25 would be considered overpriced in the context of the App Store. I'm also wondering about the type of customer the App Store will likely attract. Most discussion I've read suggests that the App Store will greatly expand the software market by attracting users who haven't bought much software in the past. Given the power-user, geeky niche that many of my programs occupy (leveraging the Mac's Unix underpinnings), I'm not certain that casual customers will be drawn to my products. Questions of pricing, sales volume, and marketing strategy come into play here. If I lower my prices, and allow Apple to take its 30% cut, could I achieve enough increased volume through the App Store to make more money? These are challenging questions.

    Another concern is this: Even if the App Store isn't de jure the only game in town, I wonder if it will become that way de facto--meaning that people don't look elsewhere for their software. Would I be losing out long-term by not being in the App Store, even if I don't like its terms or feel it's best for my products? Given the long-term arc of Apple's other transitions (Carbon to Cocoa, PPC support, etc.), it's not hard to imagine that, in four or five years, Apple might decide the App Store is the only game in town.

    Fortunately, the App Store won't be available for 90 days, and even then, I will definitely take my time to observe how the App Store takes shape and this new software market evolves, and figure out the best way to accommodate this new market with my own products.

    [/business] permanent link

    Thu, 07 Oct 2010

    QuickWho and PacketStream

    Today I've released minor updates to QuickWho and PacketStream. These releases incorporate native printing and minor bug fixes. If you use either application, these are worthwhile updates.

    [/software] permanent link

    Sun, 12 Sep 2010

    Phynchronicity 3.1

    I've released version 3.1 of Phynchronicity, my GUI for the Fink Unix software installation system. This release, the first update in nearly a year, rolls in several improvements based on the Tcl/Tk infrastructure improvements I've been involved with--native printing, sheet dialogs, clickable links in the data display, integration with the Mac's Services menu, and integration with the system Keychain. These new features significantly improve Phyncronicity's integration with OS X, and make the application more pleasant to use. They also offer more ease-of-use than other Fink GUI's. I highly recommend this update, and if you use other tools to manage your Fink software packages, it's a good time to give Phynchronicity a try. You won't be disappointed.

    [/software] permanent link

    Fri, 20 Aug 2010

    PortAuthority 3.1

    I've released version 3.1 of PortAuthority, my GUI for the MacPorts Unix software installation system. This release, the first update in nearly a year, rolls in several improvements based on the Tcl/Tk infrastructure improvements I've been involved with--native printing, sheet dialogs, clickable links in the data display, integration with the Mac's Services menu, and integration with the system Keychain. I also fixed some annoying bugs, including a crash that was caused by some changes in the underlying MacPorts framework. Taken together, these new features significantly improve PortAuthority's integration with OS X, and make the application more pleasant to use. If you use MacPorts regularly, or are a regular user of PortAuthority, I recommend this update highly.

    [/software] permanent link

    Wed, 18 Aug 2010

    Mac-native printing, revisited

    I'm now at work on integrating my cocoaprint library into my Tk applications. As I've discussed previously, cocoaprint is a departure for me in making use of Mac-native API's for printing: Cocoa for the print dialogs, and CorePrinting for interacting with the printer.

    Yet the old Unix command-line tools that I've relied on in the past to help manage print jobs have not gone away completely. In fact, I continue to marvel at the power of these tools--not only the traditional Unix tools, but also Mac-specific tools in which Apple exposes Mac-native API's to a command-line interface. While I'm no longer using the "lpr" tool to send print data to the printer, I am making use of other tools in preparing print jobs:

    I absolutely love the Mac's Unix foundations because of tools such as these, and even as I expand my capabilities with the Cocoa frameworks, I continue to lean on the Unix tools and the power they provide.

    [/general] permanent link

    Thu, 12 Aug 2010

    Last yaks

    As I mentioned the other day, I've been working on two additional Tk extensions that further improve Tk's integration with OS X, in the areas of printing and AppleScript. Today I've released them: cocoaprint, and Tclapplescript.

    As noted, the cocoaprint package (version 1.0) is a new library that uses native Cocoa print dialogs and the Mac's CorePrinting framework to implement a simple printing mechanism for Tk apps: it sends PDF files to the printer. By contrast, the Tclapplescript package is an update (to version 2.0) that simplifies and modernizes the library's API to its essential features, running AppleScript in-line from Tcl scripts and from external AppleScript files.

    These libraries represent the end of my work on Tk extensions for the foreseeable future, as I now consider Tk to have no glaring omissions in comparison to other toolkits on the Mac. This wasn't the case a couple of years ago, when I began delving into Cocoa in earnest so I could begin to fill in gaps in Tk's functionality because no one had created packages to implement these features, or because existing packages were broken in some way. Since then, I've authored several packages, contributed to others, cheered as a few other developers created their own packages (such as the statusicon extension by the aMSN developers, which puts a status icon in the Mac's menu bar), or updated their own packages.

    Because of the work that many people have done, including myself, I have asserted that Tk is now the best cross-platform toolkit for the Mac in terms of its platform-native integration--and I stand by the claim. Thanks to all who have contributed to this achievement.

    And now, let me bid farewell to the last of the shaved yaks, and let me get back to making awesome Mac apps with Tcl/Tk.

    [/software] permanent link

    Tue, 10 Aug 2010

    Further reconsiderations of "good enough"

    A few months ago I wrote that I was unhappy with certain aspects of my programs, and would spend time improving them. Of course any developer will spend time trying to improve the products he or she develops, but the reason I have to weigh the benefits of these specific improvements is that they are platform improvements--advances in the underlying toolkit that I use to develop my applications--rather than application-specific features. For instance, earlier this year I spent a lot of time developing basic drag-and-drop capabilities for the toolkit my programs use, and also developing hooks to access the Mac Services menu from my programs. These are features that I can roll into all of my programs and they enhance the user experience of my programs, but they do not extend what the application itself can do.

    I had planned to move away from platform improvements--which some call, sardonically, shaving yaks--but I an still unhappy with certain platform aspects of my programs, specifically AppleScript support and printing support. I had declared these good enough, but they really aren't. As a result, I'm back to shaving yaks.

    Here's an overview of what I'm updating:

    These two projects, which I've been working on for the past month, represent the last items on my list of improvement opportunities for Tcl/Tk native integration on the Mac--at least, the last two areas that I see within my current capabilities. I hope to do official releases of them soon, and then get back to application development--and leave yak-shaving behind for a good, long time. At that point, Tcl/Tk will truly be "good enough."

    [/general] permanent link

    Sat, 10 Jul 2010

    QuickWho 3.0: When to rewrite an app

    I've just released version 3.0 of QuickWho, my application for obtaining registration information for Internet domains. This new version is the most thorough rewrite of an application that I've ever done, so I wanted to discuss a bit about the new version and its changes.

    Earlier versions of QuickWho were basically GUI wrappers, or front-ends, for the command line "whois" tool that ships with Mac OS X. A user would type in a domain name in the search field, QuickWho would send the query to whois, and then display the text output in the main window. I tried, with the user interface, to add some features that were not directly present in the command-line tool, such as the ability to select a specific whois server to query; the ability to call QuickWho via AppleScript; and the ability to save and print the textual output for later review.

    However, despite these additional features, at its foundation QuickWho remained a simple wrapper for the whois program that offered little functionality not found in the command-line tool or in other GUI applications (such as Apple's own Network Utility, which ships for free with OS X). It simply didn't offer much value for the money I was charging for it, even after I lowered the price to $12.95. Reviews of the program, and its sales, reflected this lack of value.

    As a result, I decided to make the new version of QuickWho substantially different from the older ones. It would offer more information than a simple dump of whois output. It would be easier to use and better integrated into OS X so it could be incorporated into different workflows. After looking at a number of possible features and technologies to support these features, here is the core mix of the new QuickWho:

    I've come to re-evaluate my long-standing belief that you should never rewrite an application from scratch, which Joel Spolsky eloquently articulated. If a program is at a dead end and cannot do what you want it to, you may have no choice but to rewrite large portions of it, even the entire thing. With QuickWho, I rewrote major portions of the user interface (removing the tree view, developing and customizing the rich text view, adding the image display) and completely re-implemented the whois query, as well as the alogorithms to print the data (since it now included an image as well as text).

    With these changes, I'm restoring the price of QuickWho to its previous level of $24.95. I believe the program now does far more than the simple command-line whois tool, and previous versions of QuickWho: it offers a richer array of information about specific domains, in an easier-to-read format.

    If you need to do frequent searches of domain information via "whois," then QuickWho 3.0 is a useful tool that can increase your productivity. It's definitely worth a look.

    [/software] permanent link

    Thu, 17 Jun 2010

    Simplicity vs. power

    A big part of my design philosophy as a Mac developer is to harness the underlying power of the Unix command-line tools that reside beneath the Mac's shiny Aqua surface. This means that I attempt to expose the functionality of these tools with an easy-to-use graphical interface. As I do this, however, I am often faced with a conflict between simplicity--making the tool intuitive to use through the GUI--and power--allowing the user to access as much of the tool's functionality as possible through the GUI.

    That conflict is not an easy one to negotiate. If you don't expose enough of the program's functionality, you run the risk of "dumbing it down"--making it less useful than it should be. A GUI tool that provides only a simple wrapper to the tool's most basic functionality doesn't offer a lot of value to the user. On the other hand, if the GUI tool attempts to access every single command-line switch from the program, you run the risk of burying the user in an avalanche of configuration options and preference settings, and overwhelming all but the most advanced users--who many not need the convenience of a GUI tool at all.

    Sometimes finding the right balance between simplicity and power is straightforward. In both PortAuthority and Phynchronicity, the command-line tools that power my applications offer a managable range of functions--installing, updating, deleting, searching, and getting information about Unix software--that can easily be encompassed in a GUI. In the case of both of these programs, the GUI itself handles some functions (especially searching the list of software packages) and dispatches other functions directly to the command-line tool as required. My programs offer a more pleasant user experience over the command-line tool without sacrificing any essential or advanced functionality.

    In other cases it's harder to find the right balance between simplicity and power. This conflict is especially acute in my network monitoring tool, PacketStream. PacketStream is a user interface for tcpdump, an enormously powerful but complex network monitoring tool. The documentation for PacketStream outlines a stunning range of options, which, in the hands of a power user, results in the ability to monitor network traffic with incredible precision. It's hard for a GUI to capture all of that power without becoming equally complex to use. (Some GUI tools for tcpdump, such as WireShark, are unabashedly complicated to use.) The challenge for me is to identify the most common uses for tcpdump and provide access to a range of functions in PacketStream, without turning the program into something as complicated as tcpdump itself.

    It's still a work in progress, and I've been guided by my own instincts and user input. The earliest version of PacketStream just provided a simple wrapper for tcpdump with no options beyond which network interface it listened to (Airport, Ethernet, etc.). Over the past couple of years, I've added the ability to listen on specific network ports for certain types of traffic (such as http, e-mail, etc.), and to display the contents of packets; these are command-line switches to tcpdump options. I've also added, at the GUI level, the ability to save and print network output, and to call PacketStream via AppleScript and the Mac Services menu. These aren't hooks into tcpdump itself, but they do make the program more integrated into the Mac's GUI environment, and allow it to cooperate with other programs. Finally, I've also added some basic documentation on tcpdump itself, to assist users in understanding how PacketStream works under the hood.

    I've also removed some features, or at least moved them out of the GUI, in the interest of making the program simpler without sacrificing power. Adding Keychain support allows you to type a password once and then store the password in the system keychain: some users have complained about having to type a password everything they launch a search. I've also added functionality that automatically sets the correct network interface to listen on. In these cases there's a lot of code working to make the program more effortless to the user, with less configuration required; I've been able to increase the program's simplicity with no adverse effect on its power.

    Certainly my design decisions with PacketStream aren't for everyone. One review of the program, undoubtedly by a power user of tcpdump, complained that PacketStream is too simple, little more than a worthless GUI wrapper for tcpdump's most basic functions. I don't agree with this assessment, as there is a considerable amount of work in PacketStream to make accessing tcpdump seem effortless, but there it's certainly true that PacketStream doesn't provide access to every feature of tcpdump. Nonetheless, PacketStream is one of my better-selling programs, so at least some users are finding that it provides a good mix of simplicity and power.

    My long-term goal for PacketStream is to improve both its simplicity and its power, by making the interface more and more effortless to use, even as I gradually expose more of tcpdump's functionality. Making power seem effortless is the design philosophy of most good Mac software, and I will continue to move PacketStream--and all my other programs--in that direction.

    [/general] permanent link

    Thu, 03 Jun 2010

    Packaging vs. developing, or mainstream vs. cutting-edge

    As a developer primarily using scripting languages (Tcl/Tk and Python), I have multiple options for setting up my development environment: I can use the versions of the languages bundled with OS X; I can use one of several freely available binary installers for the languages; or I can build my own.

    The drawback of using the bundled versions with OS X is that they tend to be out of date; Apple only updates its scripting languages with a new release of OS X. As a result, the version of Tcl/Tk available on my machine is 8.4, which is a couple of years out of date.

    Binary installers--from ActiveState for Tcl and Python, or the official Python website--are very convenient, but you trade that convenience for control over your development environment. It's difficult to do non-standard or cutting-edge stuff with the standard pre-packaged distribution. My work with Tk-Cocoa and 64-bit, for instance, is too cutting-edge for these distributions; in fact, a lot of my work with Tk-Cocoa and extensions is being incorporated into the next generation of ActiveState's Tcl/Tk installer.

    As a result, I'm left to the final option of the developer--"rolling my own," or building my own stuff from source. That's actually fine in most cases. I have complete control over my environment, and I'm able to focus on what I need to do. The drawback is that if I want to incorporate something outside of my usual development environment, I have a lot of work to do because I have to build it myself.

    Recently, though, I found myself turning to pre-packaged distributions for a project--and greatly appreciating the convenience they offer.

    I have packaged up a Mac build of a popular Python-based card game, PySolFC. PySolFC is a complex package that builds on many components, including the Python PyGame library and the Python Image Library (PIL)--themselves both highly complex Python extension libraries that also build on many external libraries. I've tried to build both PyGame and PIL myself from source many times, in order to integrate them into my custom Python builds, but my efforts haven't worked: both PyGame and PIL have too many moving parts, and something always breaks. I tried again, this time using MacPorts to build the dependencies, but that didn't work either: some of the MacPorts packages were out of date or were incompatible with each other.

    Finally, after several hours of frustration, I decided to try the binary installers from ActiveState, both Python and Tcl/Tk. I moved my own builds out of the way and installed the ActiveState packages. ActiveState also provides various extension packages for Python and Tcl, and I used this method to install PIL. Finally, I used a binary installer of PyGame provided by the PyGame developers. Then, I ran the build of PySolFC using the py2app tool. The build worked out of the box. Total time spent using the binary tools: about an hour.

    In this case, I definitely appreciate the convenience that the binary packages offer. The complexities of building a library like PIL become someone else's headache (just as these are my headaches if it's my own software that I'm working on). I wanted a working build of PySolFC; the binary packages, which provide the foundation for PySolFC, make it easy to build.

    This process has given me some definite insight into the differences between being a developer of my own software and a packager of someone else's. In my own software, I want to push the limits of my toolset. That's why I'm working with Tk-Cocoa now, before it is mainstream, and also why I'm working with 64-bit applications. When you are working on the leading edge, sometimes things are difficult: for instance, I have to use the older, less capable bundlebuilder tool to wrap my 64-bit Python applications, because py2app doesn't yet handle 64-bit programs gracefully. (py2app is more powerful than bundlebuilder, scanning your application and mapping out dependencies as well as building application bundles, and as a result requires more changes to integrate successfully with 64-bit builds; bundlebuilder simply copies code libraries that you specify into an application bundle, and knows nothing about different kinds of builds.) The current maintainer of py2app, Ronald Oussoren, is also the maintainer of Python on the Mac and the maintainer of the PyObjC Cocoa-Python library. Needless to say, he's stretched pretty thin, and hasn't had time to update py2app in some time.

    As an application developer, I want to push the limits, but as an application packager, I just want something that works, that has been thoroughly tested and debugged. Using the ActiveState binary installers for Python and Tcl/Tk, and py2app, I was able to efficiently build PySolFC. The built program doesn't reflect the cutting edge of Tcl/Tk or Python--it's not built on Cocoa, nor is it 64-bit capable--but it works great, and just as importantly, it was easy to build. I definitely appreciate the convenience offered by the binary installers!

    Finally, since I release a great deal of my own work as open-source, I'm helping to contribute to the next generation of stable binary packages. ActiveState's beta build of Tk-Cocoa now includes some of my libraries. When this beta version (actually Tk 8.6) is finally released in the next year or so, hopefully the cutting-edge advances it includes will become more mainstream.

    [/general] permanent link

    Mon, 31 May 2010

    Tk-Cocoa is the best cross-platform toolkit for the Mac

    I'd like to make a bold claim: Tk-Cocoa is now, in terms of its platform-specific integration, the best cross-platform toolkit for OS X.

    With the release of tclservices, Tk-Cocoa now has a range of core features and extensions that no other cross-platform GUI toolkit can match. In other words, Tk-Cocoa provides fuller access to Mac-specific technologies--the features and user experience that help define the Mac--than any other toolkit.

    Here's how I support this claim:

    Does this mean that Tk-Cocoa is superior to these other toolkits? No, certainly not. Tk still lacks some significant features, most notably platform-native printing and a modern HTML library like WebKit. But if you're looking for platform-native integration, no other cross-platform toolkit offers as much specific support for these features as Tk-Cocoa.

    I hope this brief discussion may persuade other developers to take a closer look at what Tk-Cocoa provides.

    [/general] permanent link

    Tclservices 1.0

    I've released version 1.0 of tclservices, a Tcl/Tk library that provides access to the Mac's Services menu, allowing Tcl/Tk applications built against the Cocoa frameworks (Tk-Cocoa) to function as both providers and consumers of services. (Tk-Carbon is not supported.) With tclservices, Tcl/Tk applications can send data to other applications via the Services menu, and can also provide functionality that can be accessed from the Services menu. This package adds yet another aspect of platform-native integration that can improve Tk applications on the Mac.

    [/software] permanent link

    Tue, 25 May 2010

    PacketStream 3.3

    I've released version 3.3 of PacketStream, my network monitoring tool for OS X. This is a fairly major update. PacketStream now supports AppleScript and Services (both as a provider of a service, and able to access the Services menu); it also supports Keychain integration, which means that it's no longer necessary to type in your password each time you launch a new network scan. The other major new feature is a preference item to display the actual contents of packet data in the PacketStream data view.

    All in all, this release puts more monitoring power at your fingertips, and also greatly improves the application's ease-of-use and integration with OS X. I strongly recommend that you upgrade, and if you aren't currently a registered user, it's a great time to give PacketStream a try.

    [/software] permanent link

    Sun, 25 Apr 2010

    Reconsidering "good enough"

    Sometimes, good enough isn't good enough.

    A few months ago I suggested that perfection wasn't the ideal goal in software; instead I championed "good enough," a strategy that lets you get a product out the door that does most of what needs to be done.

    "Good enough" is indeed useful for shipping products, but I've come to the conclusion that perfection isn't such a bad goal after all--if you define "perfection" as a long-term goal that you strive for over multiple product releases. Even if you don't reach perfection, you still improve.

    The reason I'm re-considering the goal of "good enough" is that I'm still quite unhappy with some of the additions I've made to my programming toolkit--specifically, integration of Tcl/Tk with drag-and-drop on the Mac, and accessing the Services menu from Tcl/Tk applications. You can drag files and text to my Tk applications, and they provide a service that can be accessed from the Services menu. But that's a one-way street; currently, you can't drag items from a Tk application to other applications, and you can't access the Services menu from my Tk programs. This feels incomplete to me.

    So, over the past month or so, I've been working on improvements in these areas. I've gotten a working implementation of Tk applications as a "drag source" committed to TkDND's source code archive, and I've completely rewritten my Tcl Services package to properly integrate with Cocoa's Services API, both in sending data to Tk applications and accessing the Services menu from Tk applications; in the case of the Tcl Services package, it's a rare instance where a complete re-write makes sense. In fact, after a bit more stress-testing of the Tcl Services package in my own programs, I plan to add it to my growing list of Tcl extensions that provide integration of Tcl/Tk with various aspects of the Cocoa API.

    I still don't feel compelled to revisit AppleScript support and printing support in my programs; there, the current implementation is truly "good enough," in that it satisfies all my current and projected use cases, and where a re-write would represent a huge amount of work with only a marginal improvement in the functionality offered by my current packages.

    Look for these new improvements in new releases of my apps in the near future.

    [/business] permanent link

    Sat, 10 Apr 2010

    Manpower, PacketStream, QuickWho

    I've released minor updates to Manpower, PacketStream, and QuickWho. All of these updates incorporate the library bug fix that I outlined here. If you use any of these programs, this is a recommended update.

    [/software] permanent link

    Thu, 08 Apr 2010

    Windowlist 1.3

    I've done another update of my windowlist package, which implements a Mac-standard "window" menu in Tcl/Tk applications. This version, 1.3, fixes some additional bugs in the package that cropped up when I attempted to integrate it with my macdrawer package.

    Because all of my applications make use of the windowlist package, look for another round of bug fix updates shortly.

    [/software] permanent link

    Wed, 31 Mar 2010

    Is Tcl/Tk dying?

    A hardy perennial among Tcl/Tk developers is hand-wringing over the language and toolkit's standing relative to other languages and toolkits. At one time Tcl/Tk was one of the most widely-used programming combinations around, but in recent years it seems to have lost some popularity and mindshare among programmers and companies. Tcl/Tk developer Mark Roseman has posted an amusing satire about this question. David Welton has also recently posted a more serious consideration of this question. His analysis, which focuses on both the technical and cultural reasons for this erosion in popularity, is astute.

    Still, even after acknowledging the relative decline of Tcl's mindshare and community size, I still have to believe that it's little more than an inconvenience--not a fatal liability--because the core language and toolkit are still being actively developed.

    Make no mistake: Tcl/Tk's small community and mindshare are definitely an inconvenience. In Perl or Python, if you're looking for a library or extension package, it's more likely that someone, somewhere has done it already, because their communities are larger. In Tcl/Tk, you often have to do it yourself. In some instances, the functionality I'm looking for is quite difficult to implement (such as SSH support) or is already fully available in another language (such as RSS parsing); in these cases, I may turn to a language that already supports them, such as Python. And even when I do undertake an extension project, such as adding drawers and sheets, I'm often completely on my own because no one else in the community has the expertise or time to offer insight or assistance. Most of my recent posts on the Tcl-Mac mailing list go unanswered because they involve rather complex questions about the integration of Tk and its underlying Cocoa implementation. In fact, it's not an exaggeration to say that the number of active developers of the Tcl-Mac community (contributing to the language's core or with widely-used extensions) can be counted on one hand.

    But these problems are an inconvenience--not a showstopper. I am usually able, eventually, to work out any problems I encounter in developing Tk extensions. And, more importantly, Tcl and Tk are getting development where it counts most. While the releases and improvements don't come as frequently as some other languages, they do come--and there are real improvements. Of course, many of these improvements are undertaken by the scrappy core team of Tcl/Tk developers. Some of them, however, are the result of corporate sponsorship, which contradicts those who say that Tcl's mindshare is withering.

    In fact, I am heavily dependent on the Tcl/Tk improvement sponsored by a single company: Apple. Apple has twice sponsored ports of Tk to run on top of its native GUI frameworks: first Carbon in 2001, and then Cocoa in 2009. Even though the core Tk-Mac community is small even by Tcl/Tk standards, Tk itself is so widely used on the Mac (by Python, Ruby, etc.) that Apple wanted it as a first-class cross-platform GUI library. That support by Apple, especially by sponsoring a Cocoa version of Tk, ensures the toolkit's future on the platform and is the major reason I continue to develop my Mac-only apps in Tk instead of another toolkit.

    I feel very confident in Tcl/Tk's future, and am not troubled by its small community. It would be nice if it had a larger community, but as long as the language continues to evolve and grow, then I will continue to stick with it.

    [/general] permanent link

    Fri, 26 Mar 2010

    Application, not platform

    I was trying to think today of the last time I received a complaint about the user interfaces of my programs. The last time I can remember was last August, when NameFind received some pretty harsh criticism during a MacZot promotion. This was right before I began the big push to migrate my applications to Tk-Cocoa, to improve the UI style of the applications, and to improve their integration with Mac-specific technologies. The only integration issue I'm still dealing with is a fuller implementation of drag-and-drop, which I'm working on as part of an update to NameFind.

    I think those changes have paid off quite nicely. I still get complaints about the price of my applications, I still get complaints about crashes because of third-party extensions on Snow Leopard, and I still get complaints about specific features and functionality--but I don't get complaints about look-and-feel, platform-integration issues. Even if my programs are not perfect in this regard, they're good enough.

    So what now?

    For the past couple of years, at least, I've focused more on platform integration than on features in my programs. In other words, I've focused on improving and refining the user experience rather than offering lots of new functionality. This isn't a bad strategy. But I think now the time has come to shift the balance back toward development of application features, rather than improving the platform I use to develop my programs. While those platform improvements can be rolled into every one of my programs, they can't be applied in an across-the-board way to the problems that each program is designed to solve.

    I've already started moving in this direction. Updates to QuickWho and Manpower included some common features--AppleScript and Services support, most prominently--but also some differences, including price adjustments to different levels. By contrast, my update of PacketStream had more application-specific changes, no price change, and no integration with AppleScript or Services, because such features don't really make sense in this application's domain.

    NameFind, next on the update list, will get some application-specific changes, and also one big remaining platform feature that I'm working on at the same time: drag-and-drop. And the last two the last two current applications on the update cycle, PortAuthority and Phynchronicity, will likely get more application-specific changes. At that point, I'll be ready to work on some entirely new applications, which I've been planning for a couple of years but postponed because of my need to work on the platform level, rather than the application level.

    It's my hope that as I'm moving my application focus to a different level, I'll be moving my sales to a different level as well.

    [/business] permanent link

    Sat, 20 Mar 2010

    Which file search alogrithm?

    I'm working on an update to NameFind, and I'm revisiting one of its central design features: the algorithm it uses to search the file system for files with specific names.

    From its inception, NameFind has been designed to use the Unix "find" command-line tool. The find tool is very simple in its approach: it recursively scans or crawls the file system by directory, looking for file names that match the search parameters passed to it. It is very accurate, it's real-time (meaning there's no out-of-date information returned by the search), and it does exactly what it's designed to do: find files by name. The drawback to find is that while it's very fast for small searches (of a single directory or directory tree), it is quite slow for full file-system searches. It's not unusual for a full file-system search for a file name to take 15-20 minutes, and even to cause NameFind to appear to lock up while it's waiting for the search to complete.

    User complaints about NameFind have tended to focus on its speed and responsiveness, and so I've tried to find ways to speed up the search process, or at least make it feel more responsive. This is leading me to look at other search algorithms as well. Unfortunately, though, these other algorithms have drawbacks of their own.

    By far the fastest tool for searching the file system is the "locate" command. Locate works similarly to find, searching for file names that match a particular search term. It does so by scanning an index rather than recursively trawling the file system: as a result, it is much, much faster. However, the database that locate uses is updated, by default, only once a week; the obvious danger here is that its output may be outdated. It may list things that have been deleted and miss things that have been added since the last time the database was updated. As a result, while its speed is a huge plus, its accuracy is not. And while it is possible to update the locate database manually, it is a lengthy process, and doing so would detract from the user experience I'm trying to offer with NameFind.

    A third search option is "mdfind," which the Mac's command-line interface to the Spotlight search system. I originally wrote NameFind as an alternative to Spotlight because I did not find Spotlight's features especially useful for searching for specific files in specific directories. mdfind does have command-line switches for searching in specific directories for specific file names, and its output is faster than "find" because its search is based on a database search, not a real-time directory crawl; unlike locate, the Spotlight database is continually updated in real time. However, mdfind does have problems with accuracy, or at least relevancy. Spotlight, and therefore mdfind, indexes based on file content as well as file name and other data; it may return hits based on the search term being contained within the file's content, instead of its name. Spotlight also does not index certain kinds of data by default (system/hidden files, application bundles, etc.). Finally, while the built-in version of Spotlight translates its raw search output into user-friendly titles and icons, the command-line mdfind tool returns raw search data (instead of an e-mail message, it returns something like "/Users/kevin/Library/Mail/POP-kevin@ Messages.mbox/Messages/718453.emlx"). Looking more closely at mdfind, I'm reminded of why I didn't use it from the start.

    Looking at all of these alternatives, none of them is perfect. But, despite its speed drawbacks, the find tool is best suited for my design goal: to find files by name. NameFind is especially useful and fast if I'm trying to search a single directory or two with a lot of files in it; for shallow directory searches, it's better suited than any of the alternatives. It's not as good for a full-system search; while I can probably tune up its responsiveness a bit so it doesn't feel so sluggish, I can't speed up the actual search process itself. Nonetheless, I am going to retain "find" as the engine that powers NameFind.

    [/general] permanent link

    Sun, 14 Mar 2010

    PacketStream 3.1

    I've just released a significant update to PacketStream, my network-monitoring GUI for OS X. The most significant new feature is that PacketStream now automatically queries the system for the active network interface, so manual configuration of this functionality is no longer necessary. (This had been a confusing point to some users.) The program also now includes more than 30 specific network filters to monitor specific types of network traffic; the documentation has been updated to reference the expanded network parts. The application also includes various other UI improvements and bug fixes. If you use PacketStream, the new version is a useful upgrade; if you haven't tried it, please do so. I think you'll be surprised at how easy it is to monitor network traffic over your Mac.

    [/software] permanent link

    Updates for QuickWho, Manpower

    I've released version 2.2 of QuickWho and version 3.2 of Manpower. These are mainly bugfix releases; they fix a potentially serious UI glitch with sheet windows, and also add some new support options to the help menu, including a link to the Code by Kevin user forum. If you use either program, please upgrade to the latest version.

    [/software] permanent link

    Updates for windowlist and macsheet

    I've released updates to my macsheet and windowlist open-source Tcl/Tk extension packages. The macsheet package implements "sheet"-style custom dialogs for Tk-Cocoa on OS X, while the windowlist package implements a Mac-standard "window" menu for window management.

    Version 1.1 of macsheet fixes a potentially serious UI glitch in which the sheet window may be incorrectly rendered depending on whether it was invoked from a menu or a button/keyboard shortcut. The main macsheet command now includes a "source" parameter to indicate how the command was invoked.

    Version 1.2 of windowlist now offers a complete implementation of the standard "window" menu on OS X. The package raises and minimizes windows, and also implements standard keyboard shortcuts for minimizing (Command-M), hiding (Command-W) and re-opening (click on Dock) the main window.

    Both packages are available under Tcl/Tk's standard BSD-style open-source license.

    [/software] permanent link

    Wed, 24 Feb 2010


    Readers of this blog will notice that I've lowered prices on two of my products recently. You should not, however, assume that I'm going to lower prices across the board as I release new products.

    In the past I've tended to charge the same prices for all of my programs; once I set a price point for one product, the rest went to that price point as well. But I've found this actually isn't the smartest way to set prices, since it's more rooted in a desire to be consistent than in finding the right pricing balance between my product and the market. This year I've decided to be a bit smarter about pricing; I'm trying to better align my prices with the market, and back this decision up with actual sales data. My previous sales data told me that Manpower sold better at a lower price point, so the decision to lower the price of that program was easy. QuickWho sold very poorly at a higher price point, and the jury is still out on whether the new lower price point is the optimal one.

    Some products, of course, are selling quite well at their current price point, and I see no reason to lower those particular prices.

    [/business] permanent link

    Manpower 3.1

    I've released version 3.1 of Manpower, the GUI for viewing man pages on OS X. Version 3.1 is a pretty big update, building on 3.0's transition to 64-bit capabilities and Cocoa. 3.1 includes support for AppleScript and Services; it also includes a long-requested feature, the ability to bookmark specific man pages. I've also added the ability to input and display a single man page, which is something that probably should have been part of the application from the beginning. With these new features, I strongly believe that Manpower is the most complete GUI tool for browsing and viewing man pages on OS X.

    As part of the new release, I've also lowered Manpower's price a bit, from $24.95 to $19.95. This is motivated by a couple of factors. First, most of Manpower's competitors are free. While I believe Manpower's feature set surpasses any of its competitors and is well worth paying for, I can't completely ignore the market, and $24.95 may be a bit high for this particular niche. I also have actual data to support this change: Manpower was originally priced at $19.95 when it was first released two years ago, and it sold better at that price point than at a higher price point. So, I'm hopeful that the lower price will prompt you to take a closer look.

    [/software] permanent link

    Wed, 10 Feb 2010


    I'm pleased to announce the release of the macdrawer package for Tk on Mac OS X.

    This package implements Mac-native "drawer" windows for Tk. "Drawer" windows are windows are attached to the side of a toplevel window, and whose visibility can be toggled with a button. Drawers contain frequently accessed controls that do not need to be visible at all times.

    The package is available at and is licensed under Tcl's BSD-style license. Both file releases and SVN downloads are available. In addition to source code, the packages include demo scripts and man pages.

    This extension requires Tk-Cocoa to run; it is not compatible with the older version of Tk based on the Mac's Carbon framework. Tk 8.6 for the Mac is based on Cocoa, and a backport of Tk-Cocoa to 8.5 is available at

    [/software] permanent link

    Mon, 01 Feb 2010

    New user forum

    I've added a user forum section to the Code by Kevin website. This is a place for users of my products to post questions and suggestions about these products, the website, and other related subjects. I hope that users of my software will find the forum site a useful resource.

    The forum is here: Enjoy.

    [/business] permanent link

    Sun, 31 Jan 2010

    The perfect is the enemy of revenue

    Even though I've made a great deal of progress over the past year in enhancing the native integration of my programs on the Mac, I'm not entirely satisfied. My programs can now support text and files dragged to them, but you can't drag text from them to other applications. They can now be called from AppleScript, and they support the Services menu, but you can't access the Services menu from within my programs. And while my programs can now print with nice, "sheet"-style dialogs, they don't print using Cocoa API's.

    The question before me: is it better to release software that doesn't support these nice features in their entirety, or would it have been better for me to wait until the features worked perfectly?

    This is actually a dilemma that all software developers wrestle with. Marissa Mayer, Google's vice president of search and user experience, favors an incremental release process and continuous improvement. Apple, by contrast, favors "insanely great" products that are little gems of perfection. Many indie developers in the Mac community tend to embrace the Apple view of things. In the words of Brent Simmons, "You make beautiful hardware and software--you create an experience so new and compelling that people lust for these things."

    In practice, and also in philosophy, I tend to come down more on the other side--releasing even if it ain't perfect. This doesn't mean I ship programs that fail to work as advertised, that are glaringly buggy, or that lack any useful features. Some proponents of "release early, release often" see no problem with releasing stuff that crashes--hey, it's a chance to identify bugs!

    However, I do embrace Voltaire's maxim that "the perfect is the enemy of the good." In software terms, this translates to, "the perfect is the enemy of the released product." There's no opportunity for a perfect product to make money if it's not in released form. In terms of my products, this means that I'd rather partially implement the easy part of a useful feature than delay release indefinitely for a complete, perfect implementation.

    This has been my approach with drag-and-drop, AppleScript support, Services, and printing. The parts that I implemented were the relatively easy parts--and even those aren't easy. Drag-and-drop took several weeks, and a good deal of collaboration with the original creator of the TkDND extension, to implement dragging to a Tk window. Dragging text out of a Tk window is much, much harder because of technical conflicts between Tk and the underlying Cocoa foundation. I had no idea how long it might take to work through these conflicts, or even if I had the skill to do so. So I decided to move ahead with what I had.

    AppleScript support is another incomplete, difficult feature to implement. My Python programs actually have the hooks in place to provide extensive AppleScript support--implementing AppleScript commands that other applications can call--through the excellent appscript Python library. However, my Tcl applications can't provide the same level of support because the standard Tcl library for AppleScript support, TclAE, will need an extensive rewrite to support 64-bit--a rewrite I currently lack the skills to undertake. Instead, if I want to offer AppleScript support, I'll have to use Tcl's built-in "do script" AppleScript command--which means I'll have to implement raw Tcl commands that other applications can call via AppleScript. Functional, but hardly perfect.

    Services is yet another feature where the implementation isn't as perfect as I'd like. For technical reasons similar to the issues with drag-and-drop, my Tcl and Python programs can't access the Services menu from within the application itself. And they can only export Services functionality because I discovered a handy tool called ThisService, which allows you to create Services from scripting languages. I'm using the AppleScript support my programs are implementing to add the Services functionality as well. (I tried to create a Cocoa extension that would hook into the Mac's Services functionality, but was not successful--again, technical conflicts between Cocoa and Tcl that I could not work through.) While I feel my solution using the ThisService tool and AppleScript was elegant and actually quite clever, it's certainly not perfect.

    Finally, printing. It would be nice to support native printing. Yet the Mac's built-in command-line interface to printing is so adequate for my needs that it's hard to muster too much worry about the lack of Cocoa-native printing in my programs.

    My thinking about these issues is guided by more than just my desire to earn revenue by shipping products. It's also guided by the Unix philosophy of programming, which I've written about before. The key idea I'm taking away from the Unix philosophy is "keep it simple, stupid." If I can adequately implement a feature that is effective if imperfect, it's better to go that route than wait indefinitely for perfection. It's hard to say, at this point, if I'll ever perfectly implement drag-and-drop, AppleScript, Services, or printing in my programs. In 2010, my goal is to release commercial products, not open-source libraries. That means building on what I have; it's good enough. Waiting for perfection means waiting for revenue.

    [/business] permanent link

    Thu, 21 Jan 2010

    QuickWho 2.1 released

    I've released version 2.1 of QuickWho, my domain-search GUI for OS X. The big new feature in this release is support for AppleScript and Services, opening up possiblities for inter-appliction communication between QuickWho and other apps. The other big feature is that QuickWho is now a fully 64-bit application; I solved the build issues that previously prevented this from happening. This version also incorporates much of the work I've done recently in Tk itself for a better UI, and also includes a good deal of under-the-hood optimization to reduce the application's size and startup time.

    One other major change: I've lowered the price for QuickWho from $24.95 to $12.95. Previous versions of QuickWho haven't sold very much, and what sales I did receive most often came when I ran a discount campaign. I think this fact shows that the market judged QuickWho to be overpriced at $24.95, especially when you compare its relative simplicity to some of my other, better-selling programs that also have a $24.95 price tag (such as PortAuthority). I still believe that QuickWho's polish, documentation, and its system-wide integration via AppleScript and Services make it a superior alternative to command-line and freeware tools--it offers value that is worth paying for. But I think $12.95 is a more accurate reflection of its value.

    [/software] permanent link

    Tue, 12 Jan 2010

    Postmortem on 2009, and looking forward in 2010

    At the end of 2008, I posted a blog entry on what I learned that year. I didn't have time to do anything similar at the end of 2009, so I'm carrying it over into 2010. Which is appropriate, given that I am now more interested in looking forward than looking back.

    2009 was mostly a transitional year, in which most of the lessons of 2008 provided irrelevant. In 2008 I talked a lot about the importance of marketing. Regardless of my marketing strategy, the Great Recession kept sales down, down, down. I also complained about the difficulty of learning Cocoa and swore I'd never do it. But most of my technological work in 2009 was spent in learning various aspects of Cocoa and applying it to Tk, which itself was ported to Cocoa by Daniel Steffen. And finally, I said I'd add a lot of new products; instead I revived one I previously discontinued, and released incremental updates of everything else. (The single biggest upgrade of all my apps was moving them from Tk-Carbon to Tk-Cocoa and 64-bit capability, as well as UI freshening.)

    I now enter 2010 a much stronger developer than I was a year ago: I can delve into lower-level technologies when necessary (Cocoa), while still taking advantage of the rapid development features of my primary programming languages. My toolbox is much richer than it was a year ago, and with drag-and-drop, native icons, custom dock icons, sheet windows, and AppleScript and Services support, my programs will be much better Mac citizens: these are real improvements in usability, functionality, and the user experience.

    Now that I've greatly broadened my development skills, however, it's now time to begin applying it to my programs in a substantial way. The first task, of course, is to integrate these new features into my programs in appropriate ways. The next task is to explore opportunities for new applications, opportunities that my new skills now make available. I have lots of ideas, and lots of interests: the challenge will be to translate those ideas into products that users find compelling enough to pay for.

    I want to improve my sales in 2010 as much as I improved my development skills in 20009. I think I'm finally in a position to do that. Sales really surged in the last two months of 2009, to the point where sales finished at the same level as 2008--a pleasant surprise, given how slowly the year started. There's still a lot of room for improvement, but like a last-place football team that wins its last four games, I've gained some momentum. I attribute the sales spike to moving my applications to Cocoa: some of the user feedback I've gotten suggests this has made a big difference.

    As far as marketing, my product mix, and pricing, I've gathered some data about what works and what doesn't, and will keep working on that as the year goes on.

    Bottom line: despite the difficulties of the past year, I feel more optimistic about my software business than ever before. I'll be working hard to bring cool and useful products to the table in 2010.

    [/business] permanent link

    Finally, drag and drop in Tk

    This is a bit late, but I'm pleased to announce the long-awaited availability of TkDND on the Mac. This package allows you to drag files and text from other Mac applications to Tk applications. This basic GUI functionality has been a sore omission from Tk on the Mac, but George Petasis (with some assistance from myself) has done a major update of the package, including Mac support. I'm looking forward to integrating this essential library into my applications.

    [/software] permanent link

    Inter-application communication on OS X: AppleScript and Services

    One of the nicest features of Mac OS X is the operating system's support for inter-application communication. Of course, OS X's Unix underpinnings do a great deal in this respect, but the application level also provides many useful features as well. Specifically, OS X includes AppleScript and Services.

    AppleScript is the Mac's system scripting language, allowing different applications that support AppleScript to communicate with each other, exchange data, and more. AppleScript can be used to combine applications in unusual and unique ways, leveraging the strengths of each application to build complex workflows. It's not unusual to see AppleScript-based workflows that combine Microsoft Word, Adobe InDesign, and the FileMaker database to create elaborate publications, for instance. And AppleScript hooks into the lower levels of OS X as well, with a Unix-level command-line tool. No other scripting language touches as many aspects of the Mac as AppleScript. My applications make extensive use of AppleScript internally to communicate with various aspects of the OS.

    Services are a smaller, but still powerful, aspect of OS X. Services allow an application to expose part of its functionality to other applications, which can then be accessed from a system-wide menu. In accessing Services, you might highlight some text in TextEdit, select "Search with Google" from the Services menu, and then watch Safari fire up and run the selected term in the Google site. You can't really chain Services together into complex workflows the way you can with AppleScript--but, on the other hand, Services are just a menu click away.

    Most professional-level applications on OS X support AppleScript and Services to at least some degree. Not only is it a sign of the application's polish and integration with the Mac OS, it's just an added dimension of usability, of utility. My own applications have lacked this dimension, and that My own applications have not done so. As I've given this more thought, I've come to regard this as a pretty serious omission. How much more useful would NameFind be if you could highlight a search term and launch a search for a filename with that term in a specific directory? Or if you could write an AppleScript that would search for a particular software package in both PortAuthority and Phynchronicity?

    I've spent the last few weeks exploring ways to add AppleScript and Services support for my programs, and after some trial and error, I think I have the hooks in place to provide basic support for both. It will take some time--and imagination--to figure out what types of functionality to export via AppleScript and Services, but that's the fun part. And, once I'm finished, my applications will be better Mac OS citizens.

    [/software] permanent link