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
I've released version 2.6 of FileMorph, my file modification app for Mac and Windows. This version focuses mainly on Windows, with a substantially re-worked deployment structure that ensures smooth launching.
Apps written in Perl, FileMorph's main development language, are not easy to deploy on Windows. I prefer to use open-source tools rather than commercial toolkits like PerlApp from ActiveState, so I had deployed the last version using Par/PP, which creates standalone Perl application with all libraries bundled in a single executable file. Based on my research and testing, PAR/pp works fine for simple Perl/Windows applications that don't require a lot of polish.
However, for larger, more complex applications with multiple dependencies and professional-level polish--such as a custom icon, and standard application data such as version information contained in the executable--PAR/pp is seriously broken on Windows. Adding a custom icon and standard application text data is a non-trivial process, requires tools to actually hack the executable, and runs the serious risk of corrupting the executable to the point where it will not run. In my case, I got the executable to run, but at the cost of an extremely long startup time (over a minute) with a blank console popping up while everything loaded. After the application started, it still had issues: the default PAR icon still leaked out in places such as the Windows taskbar. While the app was entirely functional, it seemed rough, unpolished, and unprofessional.
This was unacceptable. I had held off on doing much marketing and promotion of FileMorph on Windows because it offered such a poor user experience out of the box. Something had to change.
After doing some additional research, I found a different approach that offered great promise: a simple stub executable that linked into Perl via its embedding API and did nothing but start the application. (The approach is outlined here: http://perl-node-interface.blogspot.com/2011/03/deploy-perl-application-on-windows.html.) I took interest in this approach because I've used something like it in my experimental ruby2app deployment tool for Ruby apps on OS X. I took the basic sample code for the Perl project, modified it to fit my application structure, and after some trial and error, got things working well. FileMorph now starts right up and, while the Windows download installer is much larger than before (60 megabytes vs. 20 megabytes), that's an acceptable trade-off for an application that runs well out of the box.
I commend this approach to any developer who is working with Perl on Windows; I am very pleased with it. While FileMorph is a commercial application, its source code is available under an open-source license at http://fossil.codebykevin.com/fossil.cgi/filemorph/timeline, so feel free to take a look. (As an aside, I also use a terrific module for deploying the application on the Mac: Mac::QuickBundle.)
And, of course, if you are an end user looking for a handy file modification tool for Windows, FileMorph may just do the trick--feel free to download and play with it. A one-time cost for a license includes free upgrades for life. It's worth your attention.Sun, 11 Oct 2015
After nearly four months since my last blog entry I'm pleased to announce the release of FileMorph 2.4.0. In terms of new features, this version is a minor update except for one thing--it now runs on Windows.
This isn't my first foray into Windows. When I tried it before, I went with an application that doesn't sell much, and I also spent longer porting it to Windows than I did trying to market and sell it--in short, I gave up pretty quickly. In this second go-round, I am planning on sticking with Windows for the long haul, because I need a second large market apart from the Mac outside the Mac App Store.
Of course, developing for Windows is not a simple process, and I had to re-learn several things about the platform; most of the last four months has been spent learning the particulars of Windows, and of re-working my development stack to support Windows. This means adding a lot of Windows details not just to a single app but to the entire suite of libraries I use to provide functionality to my applications: installation, user data, platform integration, and more. That work, at least, will be reduced with the next app I target for Windows.
I won't bore you with the technical differences between Windows and Mac--they are considerable, but not insurmountable. It is an interesting challenge to develop for a different platform, and I hope to learn more about marketing for that platform as well.Sun, 16 Aug 2015
These releases are the result of a two-month change toward looser enforcement of user registration, i.e. paying for a license to keep using the application after a thirty-day demo. I decided to make the releases nagware (they would pop up an alert if no serial number were found) but not otherwise limit their functionality, even after the 30-day demo period ended. The result was striking: without the requirement to pay, no one paid. I've had no sales over the past couple of months even with the usual number of downloads. Reviewing the rather large drop in sales revenue, I recalled this change I made to my registration code and concluded that was likely the cause. As a result, I've re-enabled the stricter registration code, and demos will once again expire after 30 days. Users who have been using the apps for the past couple of months without registering will eventually have to pay for a license if they want to keep using the apps. (You only pay once, by the way! Upgrades are provided free for life.)
Registration code is one of the duller parts of an application--a lot of housekeeping code, and surprisingly complicated, even with a fairly basic registration scheme such as the one I use. In the past my code has been prone to unexpected bugs that caused the code to freeze my application. There are a lot of scenarios a developer has to test for--the existence of a license or not, measuring how long a demo has run, and so on. It's not fun. To be honest, I eliminated the demo period because I wanted to remove the headaches of keeping the code tested and consistent. However, that code provides an essential function--ensuring that customers who continue to use my application actually pay for the work I've done. In fact, it's the most important function my code provides, from a financial perspective, especially now that I'm moving my applications out of the Mac App Store.
It's a bit disappointing that I have to use a stricter registration scheme to ensure that my work provides a bit of revenue, but I guess it's human nature to avoid paying for something if you don't have to. My code doesn't take elaborate measures to enforce registration, but it's strict enough to keep honest users honest, and that allows my apps to provide a bit of financial support for my business and family.Wed, 22 Jul 2015
The major feature powering new releases of my commercial apps today is a new open-source Tcl project I'm introducing: aem 1.0, which provides a lightweight mechanism for Tcl applications to respond to arbitrary Apple Events sent via the AppleScript programming language, Apple's system scripting language.
aem (short for "Apple Event Manager") is not the first Tcl package to provide an interface to the Apple Event mechanism. Jon Guyer's TclAE package provides a comprehensive interface to the AEM framework; it is powerful and stable. However, it is essentially a thin, low-level wrapper over a complex framework, and inherits that complexity; as a result it is difficult to use, especially if being called from another language with Tcl/Tk bindings. Additionally, it is not actively maintained these days. As a result, I wanted to move in another direction with AppleScript support in Tcl.
The aem package achieves this goal. It implements only a small subset of TclAE's functionality, the ability to respond to arbitrary Apple Events. This allows a Tcl/Tk application to be fully scriptable with AppleScript, in a manner similar to Cocoa applications written in Objective-C. (Other aspects of TclAE's functionality, such as the ability to build individual Apple Events and send them to other applications, can be achieved in a simpler fashion by using the TclApplescript package, which allows in-line execution of AppleScript code, or by executing AppleScript code using the "osascript" command-line tool.)
In addition to being a simpler implementation, the aem package also offers a cleaner, more straightforward design: it directly maps an AppleScript command with a parameter to a Tcl command with a parameter, for execution by the Tcl interpreter. The TclAE package inherits the cumbersome structure of the C-level Apple Event Manager API, which requires it to set up Tcl commands with "event" and "reply" parameters that have no relation to the Tcl code actually being executed, and which also require it to use C function calls to actually retrieve and dispose the relevant parameter from the AppleScript command. The aem package, being higher-level, delegates all that machinery to the underlying C code and does not expose it to the script level. In addition to making Tcl support for AppleScript easier to implement at the script level, this approach also makes it much easier to call aem from other scripting languages with Tcl/Tk bindings. (FileMorph, written in Perl, handles Apple Event support just fine with aem, but could not interface correctly with TclAE because of the parameter machinery.)
I've been hacking away at AppleScript support in my apps for a long time, and have been trying to find a workable solution for supporting Apple Events across the various scripting languages I use. In addition to the difficulties presented by TclAE, Perl's support has been broken for some years (see Mac::Carbon), and the appscript library for Python, Ruby and Objective-C is now actively unmaintained by its author (he discourages its use). With aem, I feel I finally have a library that will support the entire range of my applications, and I'm very proud of it.
I've released version 7.2 of PortAuthority, my GUI for the MacPorts Unix software installation system. The major feature of this release is streamlined under-the-hood support for AppleScript and some minor bug fixes. As always, this release is a free upgrade for registered users, and I encourage you to give it a try if you are a MacPorts user--PortAuthority is the only stable, actively-developed GUI client for the project.
I've released version 2.2 of FileMorph, my file modification tool for Mac OS X. The major feature of this release is a significant upgrade in AppleScript support, moving from a bare-bones implementation to a full-fledged AppleScript API, with genuine AppleScript commands that can be called from scripts and other applications. If you are looking for a scriptable application that can do batch modification and renaming of files and directories, with an intuitive UI, FileMorph may well fit the bill.Mon, 13 Jul 2015
Hot on the heels of Manpower'srecent upgrade, I've released version 6.1, which features some significant fixes in how Manpower registers itself as the default viewer for man pages on OS X (crashes were a regular occurrence), and also a significantly improved mechanism for responding to Apple Events. The two libraries powering these features are ones I plan to formally announce as open-source components in the near future, after a bit more testing and work on them.
As always, Manpower is a free upgrade to registered users. This also includes users of the Mac App Store version; I've been in contact with several people to whom I've provided free serials in recognition of the discontinuation of the Mac App Store version. Feel free to give the new version a try.Sat, 04 Jul 2015
I've released version 6.0 of Manpower, my Mac program for browing Unix system documentation, or man pages. As I've discussed recently, I've decided to withdraw this app from the Mac App Store, and so it will be sold only from my website.
This version of Manpower includes a UI refresh and some general refinements in performance. I feel it is the nicest app on OS X for viewing Unix documentation, and is well worth your time if you need to understand how something on your system works under the hood.
As always, it's a free upgrade for registered users. Give it a try.Tue, 30 Jun 2015
Now that I've begun that work, I find my heart simply isn't in it.
My heart is with the Mac.
I've done enough work on Windows and Linux to know that I can certainly develop for those platforms, but there's a reason I stay with the Mac--even using a cross-platform toolkit. It is by far the best environment for developers. I absolutely love developing for the Mac, even in spite of Apple's many restrictions, even as I move out of the Mac App Store for good.
If my work on the Mac isn't very rewarding financially, it can at least be rewarding in terms of enjoyment.
Reading Brent Simmons' recent blog entry, "Love," crystallized this for me:
Write the apps you want to write in your free time and out of love for the platform and for those specific apps. Take risks. Make those apps interesting and different. Don't play it safe. If you're not expecting money, you have nothing to lose.
I'll keep open-sourcing key components of my apps, and of course I will continue to do my essential open-source work as maintainer of Tk on the Mac. But I will also continue to do my own commercial work, making what money I can, and making the best apps I can.
You always come back to what you love.Sun, 28 Jun 2015
I am undertaking some fairly significant changes to my apps.
First, I have decided to open-source all my code, while still charging for pre-built binaries. I'm a strong proponent of open source code, and this move has been in the back of my mind for years. I have nothing to hide in my code. Others may find the code, not just the apps, useful. So I am in the process of establishing open-source repositories of all my code at http://fossil.codebykevin.com, using the elegant, superb Fossil source code management tool developed by D. Richard Hipp, author of the hugely popular SQLite database. I am first making available various libraries and packages I use in all of my applications, and then will follow with the source code to the apps themselves.
Second, I will be taking my applications cross-platform whenever it makes sense to do so. I would like my apps to be as widely used as possible, and this means that I would like to get them on more platforms than just the Mac. In practical terms this means I will be re-working the applications' code a bit to account for differences in platforms (Windows and Unix/Linux have different keyboard shortcuts than the Mac, for instance). I expect these differences to be fairly minor. The larger challenge here will be to set up processes for building and deploying the applications on each platform. (I expect to provide pre-built packages for Windows and Mac, but because of the diversity of platforms and deployment systems in the Unix world, I will only provide source code there.)
Third, these changes will require not just some modification of my applications' source code to fit in reasonably on each platform, but a simplification of the code design. In practice, this means removing code that is not essential to the application's functionality, or re-implmenting code in a simpler, more cross-platform way. I have a lot of Mac-specific code in my applications that requires compilation and which provides features that does not exist on other platforms (the Mac's Services API, for instance); I also have complex platform-specific code that can be implemented in a simpler, script-based cross-platform mode (printing files, for instance); I also have platform-specific code that expands functionality already provided by Tcl/Tk's core API's (application scripting) without much benefit. In deciding to keep or abandon native API's, I am going to look at whether the functionality is essential to the app and if it cannot be achieved in a similar way using a simpler approach. If the answer to both questions is yes, then the native functionally will stay. Otherwise, the functionality will be removed or re-implemented.
You may wonder about the business case for open-sourcing my code. Will this allow anyone to download my apps for free without paying for them? Well, in theory, yes; anyone can download and patch my apps for their needs. But building my apps is a non-trivial process--most people are not software developers--and I don't expect that many people are going to be inclined to bang away at the steps needed to patch and build my apps. There is still a huge convenience factor in providing an easy-to-install package from the get-go. Given that I am not currently seeing huge sales on the Mac, the upside to expanding my distribution to other platforms far exceeds the risk I am undertaking by open-sourcing my code.
Concurrent with this change, I plan to phase out my involvement with the Mac App Store. Like many other developers have found, my sales in the app store have dwindled to almost nothing, and the increasing technical restrictions on apps deployed there have simply become too large a headache to deal with. (See this discussion for more detail.) I still plan to remain a paid member of Apple's developer network, because of other benefits it provides (documentation, code-signing certificate, etc.). But I also plan to pursue other platforms as well.