Code by Kevin, Programming, code, business, and other pursuits
Kevin Walzer, software developer.
Subscribe to RSS Feed
Get a syndicated feed of my weblog.
Site design: Skeleton
After my recent discussion of finding the right mass of customers, and given the ambitious task I've set of doing major updates of all my apps, I've also taken on another difficult task: deciding how many apps to move forward with.
I have one steadily-selling app (PortAuthority), and several others that sell in volumes ranging from modest to non-existent. PortAuthority is not far enough ahead of the rest to sustain my software business by itself; instead, it accounts for about half my sales overall, while a cluster of my other apps accounts for the other half. Of that cluster, several apps show up in modest numbers individually, and some contribute only a sale or two per year.
I've been very reluctant to decide to drop any of my apps, since I've invested a good deal of effort into each of them, and all solve problems I've had at one time or another. However, the scale of the app updates I'm undertaking is rather large, and I simply don't have time to invest in that level of work for an individual app that isn't selling. So, today I took a hard look at sales numbers, and have decided to drop three apps from my lineup: my file renaming app FileMorph; my file search app NameFind; and my UI for Fink, Phynchronicity.
None of these apps have sold more than a couple of licenses per year over the last few years. Phynchronicity got some nice attention when it was first released in 2007, and was a solid seller for a few years. But its sales in recent years have dropped to near zero. By contrast, NameFind and FileMorph never took off at all and only registered sales when accompanied by heavy promotion and discounting. All three apps are in crowded markets with a major incumbent or lots of competition, and it was just hard for them to get any sustained tractions. (By contrast, PortAuthority is the major established incumbent in its market niche, and no other competitor has been able to gain traction.)
Somewhat to my surprise, other apps such as QuickWho and TextSweep have found modest, but steady, sales on the Mac App Store. These apps, along with Manpower, are not stellar performers individually, but each contributes to an average monthly sales total that is about equal to PortAuthority. In contrast to the apps I'm dropping, these apps are in more focused niches and don't seem to have a lot of competition; for a small but sufficiently large number of users, these apps fulfill a need. Apps of this kind also really benefit from being in the Mac App Store; while the App Store is crowded, it offers such a huge potential market of Mac users that it's easier to reach the small number of users who might be interested in my apps.
Reviewing my sales numbers and deciding to drop some slow sellers accomplishes two things for me. One, it will allow me to better focus my efforts. It's easier to update five apps than eight, especially when one of the apps, Phynchronicity, would require significantly more time to update than the rest. Second, this review pretty much answers the question I posed previously: I'm having more success targeting narrow niches, where there isn't much competition, rather than large niches. This also means that any new apps I develop will be geared to smaller niches rather than large ones, and will focus on being included in the Mac App Store. Except for PortAuthority, my non-Mac-App-Store sales are pretty negligible. (PacketStream, my Mac network monitor, cannot be in the Mac App Store, and its sales numbers just made the cut--but it sells far less than PortAuthority.)
This has been a useful and productive process. I'll be able to finish updating my remaining apps fairly quickly, and I'll be able to do incremental updates much more frequently with a smaller number of apps; this has been a real challenge for me in recent years. And I'll be very careful before deciding to add any new apps, as well.
Thu, 31 Oct 2013
I've spent the last few days updating and tweaking my server installation, which happens to be OS X Server running on an iMac in my office. I've posted some observations about Mavericks Server here. Brief summary: Mavericks Server is a powerful, inexpensive, easy-to-use server platform that, in its current incarnation, offers the smoothest upgrade experience of any Mac server I've ever installed. Check out the link for more details.
Fri, 11 Oct 2013
As I discuss plans to keep my prices at the higher end of the "indie-shareware-utility" market (around $30) to keep slightly better revenue in the face of low unit sales, this also prompts me to consider why my sales are pretty modest, and lower than a few years ago.
There are two common reasons for low sales: you're in a crowded market and it's hard to get noticed; or you're in a niche market that only a few people care about. Either way, it's hard to get a critical mass of customers. In discussing my app strategy on various mailing lists such as the MacSB group, the advice most other folks give me focuses on the latter: in general my apps provide nice graphical user interfaces to command-line utilities, and the most frequent users of such utilities are people who do not want or need GUI's--hence my potential customer base is pretty small. Because it's hard to reach a big enough group of customers in niche markets, developers like Marco Arment advise against developing "niche" apps.
Fair enough. An obvious alternative strategy is to target larger app markets with more potential customers. But the obvious challenge here is that there is more competition in larger markets, and it's harder to get noticed. This is especially so today in light of the Mac App Store; it seems pretty clear that the Mac App Store has attracted more developers into the Mac orbit. It's hard to prove definitively, but my overall sales dropped quite a bit after the Mac App Store opened up. Because there's more competition in the Mac space, there are developers like Justin Williams who advise against targeting larger categories because they are too crowded.
Well. If small niches are too small, and large niches are too crowded, what's left?
I think the best solution is to be realistic about your prospects: reaching customers is hard, and now it's harder than ever. Paradoxically, as the Mac app market gets bigger and more crowded, the chances of any individual developer standing out and earning high sales is reduced. (In this respect the Mac market is becoming more like the Windows market.) I think this is one reason why a lot of Mac developers focus more on contract app development for the Mac and iPhone market rather than on trying to make and sell individual apps to end users. If they develop individual apps, they are more apt to be portfolio pieces than serious products with a large customer base.
If it's a given that your app is likely to be a modest seller and that any chance of breaking out of the pack is going to rely on factors beyond your control, what's left is to follow your muse: make apps that address some need that you see, perhaps something that scratches your own itch, and make them as good as you can, regardless of whether it targets a large or small niche. You are much more likely to create an app that reduces pain for someone else, and therefore is worth paying for, if you are reducing your own pain in the process. It's always a risk that your app will only have an audience of one, but if you make it awesome, and put a little business sense behind it in terms of marketing and presentation, it's likely that you'll reach at least a few other users who will give you money.
Let's face it: This may require you do to something else for your living. But then again, that's always been the case. And if you make an awesome app that others give you money for, you still have a chance, however slim, to be one of the exceptions.
If one lowers prices, that needs to be offset by a corresponding increase in sales volume sufficient to offset the lower price. Otherwise, you're simply left with less revenue.
Because the lower prices didn't really move the needle on sales, I have little choice but to restore the older prices if revenue is to remain consistent.
I've tried this trick enough that I don't see much point in trying it again in the future. I may run promotional prices in the future; I have done so in the past in partnership with MacZot, MacUpdate, and Bits du Jour, but these were usually one-day or one-week promotions that provided a nice short-term boost in sales. As for my own discounts, though...I think that's done.
Mon, 23 Sep 2013
In a previous entry I outlined an update roadmap for my apps that focused on taking a step back from native UI integration and more on under-the-hood integration between my cross-platform development framework (Tcl/Tk) and OS X. I'm about done with applying this strategy to PacketStream. Because the changes to PacketStream are going to serve as a template for the rest of the app updates as well, I wanted to take some time to discuss them in detail.
Less native UI integration
I am moving away from the extensive wrapping of native widgets in favor of a modified approach that makes use of Tk's native foundation but also takes advantage of Tk's flexibility with configuring appearance. For instance, in place of a native NSToolbar that cannot be easily configured from Tk, I've opted for the standard Tk approach of setting up a group of toolbuttons within a frame using a custom font to display icons, and using Tk to style both the buttons and their tooltips. This is simpler to set up and also is snappier in performance; the NSToolbar approach was harder to configure, slower to load and, for some reason, subject to flickering, especially in displaying tooltips. Note that this approach still makes use of under-the-hood native integration; I had to write a custom library calling Core Text functions to load the icon font. But this approach has the advantage of allowing me to use font icons, which are resolution independent and naturally friendly to Retina displays, rather than native bitmaps, which are not Retina friendly without considerable rigamorole. Bottom line: My UI is now easier to set up, runs better, and supports emerging hardware features on the Mac platform (Retina support).
The screen shots below illustrate the older and newer layout of PacketStream.
Greater integration under the hood
I'm taking a step forward toward better integration under the hood. One good example on this is how I call external processes that need escalated privileges, such as running tcpdump (the network monitoring tool that powers PacketStream). If someone is launching tcpdump from the command line, they'll do so by calling "sudo tcpdump"; sudo is a command that gives "superuser" privileges to the user launching tcpdump. Native GUI apps use a somewhat different process that presents an "authorization" dialog to the user (such as a software installer); I have, however, been unable to get this approach to play nicely with the design of my Tcl apps, and so have resorted to presenting a dialog that calls for the user's password and pipes it under the hood to "sudo." This approach has served me well for several years, but as I have continued to research the question, I've come to the conclusion that using the user's "sudo" password in this fashion presents a security risk because the password is transmitted, under the hood, in plain text. I finally devised a solution that allows me to make use of the native authorization dialog based on the work of another Mac developer, Ian Waldham, and that's what I'm rolling out in my applications now. It's more secure, provides very clean integration, and, in my testing, allows my app to perform better as well. Bottom line: Improved under-the-hood integration provides better performance and security.
The screenshots below illustrate the older and newer, more secure, native authorization dialog.
More muted look and feel
One reason for moving away from wrapping of native widgets such as the NSToolbar is that they are not very configurable--it is hard to modify their appearance to keep up with evolving UI trends on the Mac. This may be subjective, but it matters; my apps making use of the native Cocoa toolbar look dated compared to other apps running on recent versions of OS X, which are more muted in color. It's not just a matter of changing icons; it's also matter of overall color schemes, the size of buttons and their layout, and more. Switching to a more Tk-centric approach (which uses native components such as Cocoa buttons and frames, but which does not lock you into structured Cocoa widgets such as the toolbar) gives me more flexibility to keep up with these UI styles. As a result, if you look at the screenshots above, you see a big difference in the old and new version of PacketStream. The old version is more authentically native, but now looks stuck in a time warp. The new version, while it looks somewhat less native in its overall layout, nonetheless does not look out of place because it picks up current styles with color, icon format, and more. Similarly, if you look at the icons below, you'll see a big difference in the old and new versions. Bottom line: It's important to use an app structure that lets you readily modify the general look of the app to keep up with evolving UI trends.
The screenshots below illustrate the older and newer, more muted, icon style.
I'm going to hold off on releasing the new version of PacketStream because I want it to be of a piece with my other apps; I'm hoping to have all of the new apps ready for release, along with a website makeover, early in 2014. But I wanted to give some concrete evidence of the direction these apps are taking. I'm happy with the progress thus far.
Thu, 29 Aug 2013
Maintaining and updating several applications at once isn't a simple process, especially if you don't have as much time as you'd prefer. After putting out point updates of a couple of my apps that implemented some of the work I've been doing this year, and planning to roll out similar incremental releases of my other apps, I've decided to hold off on any further incremental releases and just update everything in one big bang. This is definitely a case of mission creep, as my plans are now evolving in the direction of a complete user interface (UI) refresh of my apps, many revisions in their under-the-hood features, and revisions of their branding, but I think it's the best course to pursue.
In general terms, here's what the changes portend for my apps:
Why all these changes? Declining sales are one reason; I'm not satisfied with the way my apps have sold in recent years and I think it's time to try some major changes. But, apart from that, I also want to put the apps on a platform for continued evolution. That's a necessary task. I think they've gone as far as they can go in their current configuration and more than minor tweaking is required to get them ready for their next five years of life. That's the larger purpose of this project, even if sales don't revive to a dramatically higher level.
I realize that until I release them, these changes are just vaporware. My goal is to have them out after the new year, but time will tell.
Comments are closed for this story.Sat, 03 Aug 2013
The new versions will support a vastly improved update experience going forward by integrating Sparkle support, the popular framework for app updates that is still used by hundreds of apps that are downloaded from outside the Mac App Store. Sparkle does not have any obvious hooks that would enable it to be directly integrated into Tcl/Tk applications, but I was able to integrate the framework's functionality by adapting the Sparkle Helper App by Marco Schuh to my own projects. (To see the source code for my Sparkle Helper app, go to http://sourceforge.net/p/tk-components/code/134/tree/.) My own homegrown updating system has had some hard-to-track bugs in recent versions of my apps, and I just decided to abandon it in favor of Sparkle.
Other than Sparkle integration, both apps feature bug fixes and other improvements (PacketStream gets a more responsive display; NameFind has better Growl integration). I've also lowered the price of the apps a bit, from $30 to $20, in hopes that this will invite more folks to give them a try.
As always, upgrades are free to registered users. And these are just the first round of updates I have planned for these apps. As we enter the second half of 2013, I'm moving ahead with rolling out some of the work I've done on different levels of Mac integration in my apps. Sparkle support is a good example of this, but it's not the only one.
Comments are closed for this story.Wed, 03 Jul 2013
A few months ago I decided against using Perl as a desktop development language, as a result of some limitations I had run into in updating and deploying some Perl libraries. I have had a bit of free time this week to revisit the problem, and happily, I've found a solution. As a result, Perl is now back in my toolbox, and I look forward to working on some new apps in the language in the near future.
Comments are closed for this story.Tue, 02 Jul 2013
I've scratched another small itch in my app development by creating a Cocoa-style popover window for my Tcl/Tk apps.
After looking at the Cocoa docs for NSPopover, I concluded that it isn't feasible to implement such a window natively in Tcl/Tk by implementing some kind of integration at the Objective-C level--there's no way to place Tk child views in the genuine NSPopover. However, Tk provides enough hooks to implement something reasonably close in look and behavior.
I've posted some sample code implementing the popover window here. It's not really feasible to make this a general package, but the sample code should be easy enough to adapt for individual Tk apps.
Comments are closed for this story.Sun, 02 Jun 2013
I've released version 1.1 of my "fullscreen" open-source library for Tcl/Tk apps on the Mac. This package adds native a "fullscreen" button to Tk windows on Mac OS X 10.7 and later. This release, which is a fairly major under-the-hood rewrite, fixes a major bug with window geometry when the app took fullscreen status (widgets such as buttons would not respond to mouse clicks but instead the click would register a few pixels underneath the widget). For more information, and to download, see http://opensource.codebykevin.com/native.html. Thanks to Andrew Stein for the bug report.
Comments are closed for this story.