Getting the best out my apps’ auto-update system

Over the last couple of weeks, I have been progressively rolling out updates to my apps with the aims of:

  • ensuring their optimum compatibility with macOS 10.15 Catalina, as far as I can at this stage;
  • improving your and their security by checking the code signature each time they start up;
  • adding my auto-update system to save you from having to look for the latest updates. When I need to make changes for Catalina this is an important step for all of us;
  • adding various interface improvements, such as remembering window size and position, and supporting different text sizes where I can.

So, far the following apps have had the first three (and some the fourth as well) applied to them:

  • 32-bitCheck 1.8
  • Apfelstrudel 1.3
  • Cirrus 1.5
  • Consolation 3.2
  • DelightEd 2.0b2
  • Dystextia 1.6
  • LockRattler 4.21
  • Nalaprop 1.0b10
  • Podofyllin 1.0b17
  • Revisionist 1.4
  • SystHist 1.11
  • T2M2 1.7
  • xattred 1.1

If you want another app given priority in this update series, please let me know and I will update it sooner. My aim is to have all my apps which will support Catalina updated fully before its release in the autumn/fall.

I have also updated each of my four command tools so that they are Catalina-ready, in terms of notarization, but they don’t have code integrity checking or auto-update, of course.

Changes to check code integrity and for auto-update only affect these apps when you open them.

1. Code integrity check

Shortly after opening each time, the app checks its contents against its code signature. If there is a discrepancy, it quits but does not crash. If this happens, you will see the app start to launch normally, and a window may briefly appear before it quits. You should, of course, never see it quit like that, but it is a fairly robust way of ensuring that nothing has happened to the code on disk. From my understanding of what Catalina will do, this check is still worthwhile even when running macOS 10.15.

2. Auto-update

This is designed so that it just works, and you don’t have to fiddle around with any settings at all.

When you open each of those apps, once it has performed its integrity check, it then looks to see when it last checked for an update. If that was more than 12 hours ago, it connects to a list on my GitHub server to check if there is a newer version available. It passes no information at all to that server other than minimal statistics gathered by GitHub: I have no idea which apps connect, nor where they are being used.

If there is a newer version available, it displays a simple dialog offering to download the update. If you accept the offer, that is performed by your default browser as a normal Web download, with quarantine flag and full security checking. The update then arrives in the background in your default downloads folder, for you to install whenever you wish, in exactly the same Zip archive as you’d get from here. I don’t store those updates on GitHub, but here in the main blog resource files. That connection uses HTTPS.

If there isn’t a newer version available, then the app saves the time of the check in its preferences file, and uses that to decide when to check for an update again.

When the app has checked for an update, regardless of whether one is available, the last item in the Help menu will read
√ Checked for update
When it hasn’t checked for an update, because it’s less than 12 hours since it last checked, that item reads
Update not checked
(both in grey ‘disabled’ text, as they aren’t menu commands).

You don’t need to do anything to the app’s preferences to enable that default behaviour. It should just happen.

If you see there’s an update and want to download it early, each app still has its Browse Updates command in the Help menu which makes that simple to do.

3. Customising Auto-update

If you maintain copies of my apps on a network, or use your Mac in unusual circumstances, you may wish to customise that behaviour. Rather than add a preferences dialog to each app, this is done in Terminal, and explained in the Help book for each app, and any separate documentation.

For an app whose ID is co.eclecticlight.Appname (the same as the name of its preferences file), you can disable all update checks by entering
defaults write co.eclecticlight.Appname noUpdateCheck true

Similarly, you can set the time interval between update checks to 6 hours instead of 12 by entering
defaults write co.eclecticlight.Appname updateCheckInt '21600'
where 21600 is the interval in seconds (60 * 60 * 6). If you want to set the interval back to 12 hours, you can either enter
defaults write co.eclecticlight.Appname updateCheckInt '43200'
to do it directly, or enter
defaults write co.eclecticlight.Appname updateCheckInt '0'
as values of less than 1 will force the app to reset the interval to that default value.

4. Don’t edit the preferences file

As with most apps, preferences are managed by a mysterious service named cfprefsd, which keeps them in memory a lot of the time. If you try editing the preferences file directly, or even believing what it apparently says, you will run into trouble. Even when you have quit the app, cfprefsd may not synchronise its view of those settings with the file on disk for some time. Please leave the app to get on with the job, only changing settings using the commands given above, or you’ll get very confused.