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
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.Wed, 13 May 2015
I've released version 2.1 of FileMorph, my tool for batch operations on files (renaming, changing modification dates, etc). This release is the result of a larger-than-anticipated effort to add AppleScript support for the application, and will be released on my website only--not in the Mac App Store.
I won't bore you with the technical details of why it took months to get AppleScript support worked out. Perl used to have very good support for AppleScript, but the Mac::Carbon extension library that, among other things, enabled AppleScript integration has not been updated for several years by its maintainer, Chris Nandor. (Apple's deprecation of Carbon makes updating the Mac::Carbon package a daunting task, as huge swaths of it no longer work and will need to be rewritten or removed.) My knowledge of Perl's low-level code to integrate natively with OS X is not good, and so I was not able to take the task on myself. As a result, I fell back on using Tcl's built-in support for executing Tcl code from AppleScript, substituting Perl commands for Tcl in this case. The result is a basic, but adequate, package of AppleScript support that can be used to automate FileMorph's functions, a mark of a polished and professional Mac application.
Unfortunately, I did run into some insurmountable issues with AppleScript and the Mac sandbox, which limits the operations an application can support. While in theory the sandbox should not cause any problems with AppleScript, in this case it did, perhaps because my application requires access to any directory on the user's hard-drive--a big no-no with the sandbox. Proceeding with a Mac App Store submission would require removing AppleScript support, a compromise I am unwilling to make.
I've loudly pulled my applications from the Mac App Store before, also because of issues with the sandbox, and subsequently tried to make things work with the sandbox to get the apps released in the MAS. I don't see that happening this time with FileMorph. Not only are the technical issue more intractable, but the business case for the MAS makes less sense than it used to: my sales have declined in the MAS to the point where it will hardly matter to my bottom line whether I sell there or not. Given the work required to maintain a sandboxed version of my app, the financial return does not seem worth it. If I have to maintain two versions of my app, it had better make sense financially. (I've even given thought to porting FileMorph to Windows, though no decision has been made there.)
I'm not going to make any sweeping announcements or policies about my apps in the MAS: they will be determined on a case-by-case basis. But the continued technical hurdles, combined with diminishing financial returns, make it hard to justify the work required to keep that sales channel open.Sat, 21 Mar 2015
I've just committed another big batch of patches to Tk-Cocoa, submitted by Marc Culler, that address some significant lingering issues with memory management, zombie windows not being removed, and event loop integration between Tk and Cocoa. Not only have Marc's patches made Tk run smoother and faster, they have also simplified the code in many places by removing outdated API calls and improving the comments on what the code does.
Marc submitted these updates after many hours of work in the interest of getting the visualization application he co-develops, SnapPy, running better with Tk-Cocoa: it's a large, complex application that really pushes Tk hard, and showed a lot of the bugs that persisted in Tk-Cocoa even after the recent updates. After these were done, he reported that SnapPy runs beautifully. My own testing shows that Tk is running better than ever, and some of the old reports that illustrated showstopper bugs simply don't display issues anymore, at all.
I wanted to highlight Marc's contributions because they go beyond fixing a specific bug or implementing a specific feature, as valuable as such contributions are; he has helped to substantially re-design Tk-Cocoa's implementation and documentation to be simpler, faster, and easier to work with. He has essentially served as co-author of this version of Tk-Cocoa, and I am enormously grateful that he has invested the time and patience to learn the relevant API's and propose changes that don't just fix specific issues, but substantially improve the whole. In gratitude for his contributions, I've credited him as one of the main authors of Tk on the Mac, along with Daniel Steffen, Jim Ingham, and Ian Reid, whose work has made Tk possible on Mac OS X.
Now that SnapPy is ready for a new release soon, I don't expect Marc to remain as busy with submitting patches: he can get back to his day job as a mathematics professor at the University of Illinois-Chicago. Now I truly believe, in no small part because of his work, that Tk-Cocoa is now the stable, fast, simple toolkit that all of its users need it to be on the Mac--and I encourage anyone who is still hesitant about moving to Tk-Cocoa to take the plunge.