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


Sun, 15 Jan 2017

Changes in app update mechanism

I'm working on a round of application updates that are focused on (yet another) re-work of their application update mechanism.

This change has been driven by three factors: the recent upgrade of my websites to support encryption via Let's Encrypt; changes in Apple's API's in macOS Sierra to require encryption in web connections, and in how app updates can be installed on the system through a mechanism called App Translocation; and a desire to simplify the code of my app updates mechanism.

Let me address each of these in turn.

Encryption: This one is pretty easy. It just requires the addition of a Tcl library, TLS, to support encrypted web traffic. In addition to including the library, it requires a few lines of Tcl code, and then everything Just Works.

Apple's API's. The encryption part is simple, as discussed above. The "app translocation" API has taken me a bit more time to figure out and test; the only file format that Apple will allow to avoid app translocation (in the name of system security) is a signed disk image, or DMG. Zip files, tar files, and other formats don't get that benefit. (In app translocation, an affect application is copied to a hidden read-only format and then launched, to avoid injection of malicious code in the process; it also means the app cannot be updated or otherwise modified while it is running, which makes updates that Mac users expect impossible.) Using signed disk images instead of zip or tar formats is simple enough, and I've gotten it working after some trial and error.

Dissatisfaction with my code. For years I've tried to emulate the popular Sparkle app update mechanism in my apps. First I tried a basic imitation; then I tried to actually integrate Sparkle into my work; then I tried to use many of Sparkle's mechanisms under the hood and layer my own implementation on top of it; and, now, I'm back to doing a basic imitation. The reason for this is that I've never been able to cleanly integrate Sparkle itself into my work; it integrates perfectly with applications written in Objective-C, but I've never been able to figure out how to call it directly from Tcl, even if there is a C layer between. Later I used Sparkle's XML "appcast" mechanism under the hood, but this added a lot of complexity; Tcl's XML-parsing libraries don't play well with other scripting languages, which meant that I had to write additional code to parse the appcast if the application was written in, say, Perl. Additionally, my Tk-based knockoff of Sparkle's UI was just plain ugly.

So I'm back to a basic Tcl implementation that more or less follows Sparkle's example, using the following steps:

  1. Application pings my server to check an app version. In my case this is a simple Tcl file with one line of code: the new app version.
  2. App compares the new app version with the installed app version. If it's the same, it presents a native dialog stating so. If there's a new version, it downloads a list of changes from the server stored in a separate Tcl file.
  3. If the version is new, it asks the user if they want to install the new version. If the answer is no, the update exits. If the answer is yes, the app downloads the new version in a DMG file, mounts the DMG file, and informs the user the new version is ready for installation.
  4. When the user begins installing the new version, the running app moves itself to the trash, copies the new version of the app to the install location, launches the new app, and exits.

This format works pretty identically to Sparkle, at least in its basic moves; it's much simpler to maintain; and it will be portable to another platform, specifically Windows, whereas Sparkle is Mac only. Some Windows-specific code will be necessary to accommodate the differences in Mac and Windows installers, but apart from that, it will be identical.

I'll begin rolling this new update mechanism out in my apps in the near future.

[/software] permanent link