Author Archives: philastokes
The idea behind BackupCam is to keep a continuous, rolling video of the last few minutes of activity on your mac, in just the same way as dash cams in cars work.
There’s a couple of scenarios where this might be useful. If you’re working on a project where ‘undo’ doesn’t always work reliably or when you most need it to – Xcode, for example, can often let you get your project in a mess without offering you a clear path as to how you got there or how to get back, short of discarding all changes in a particular file – with BackupCam you’ll be able to see exactly how you got to where you are.
Similarly, BackupCam can also help you to review changes that you may not have noticed at the time – perhaps if you were distracted by something else happening, either on screen or off. This can help both as a security and a troubleshooting tool
BackupCam can record up to the previous 30 minutes activity, so may help you recover something that is missed even by Time Machine or other traditional file backup mechanism.
More details are over on the BackupCam webpage, but I’ll just note here that BackupCam can also be controlled by AppleScript, with all the flexibility that that offers. Here’s a sample script that checks whether the last recording was longer ago than the time interval set in BackupCam. If it is, it kicks off a new recording session:
BackupCam is still in the early stages of development (we’re calling v1 a beta), so please feel free to report any bugs or enhancments you’d like to see. At the moment, it requires 10.11.6 or higher and only records the main display. I plan to add support for multiple displays in a future update.
Is it me, or is AppleScript experiencing something of an Indian Summer? It seems everywhere I go, people are talking more about macOS automation, AppleScript and even Apple’s curious hybrid syntax AppleScriptObjC (ASObjC).
Of course, some people have suffered miserably at the hands of AppleScript in the past, and even though the thought of scripting with access to Cocoa APIs through Objective-C is tempting, they fear the AppleScript side of it.
If that’s you, bear in mind that AppleScriptObjC isn’t really “AppleScript + Objective-C” at all. It is actually just a dialect of Objective-C that will be accepted in the (Apple)Script Editor and can be run by an instance of the AppleScript component. In plainer English, you can use Objective-C in an AppleScript without any AppleScript whatsoever!
The point of doing so would be that one could package Objective-C code in a .scpt file (or scptd bundle or AppleScript .app), and also mix whatever scripting language you prefer with calls to Cocoa’s APIs.*
The problem that using ASObjC presents anyone familiar with Objective-C is how to translate ‘pure’ Objective-C into the dialect that Script Editor (and other applescript runners like FastScripts, Keyboard Maestro, Automator, etc) can understand. If you use LateNight Software’s Script Debugger for scripting, you’ll already know that the work is done for you by the app’s built-in code completion. If you’re battling on in Apple’s default Script Editor, you’ll need to do the translation manually.
By way of example, then, here’s some original Objective-C, and below it, a translation that would work in Script Editor:
NSString *aString = @"hello";
NSString *bString = @" world";
aString = [aString stringByAppendingString:bString];
NSUserNotification *notif = [[NSUserNotification alloc] init];
notif.informativeText = aString;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notif];
set aString to NSString's stringWithString:"hello"
set bString to NSString's stringWithString:" world"
set aString to aString's stringByAppendingString:bString
set notif to NSUserNotification's alloc's init
set notif's informativeText to aString
NSUserNotificationCenter's defaultUserNotificationCenter()'s deliverNotification:notif
As you can see, there’s a direct 1-to-1 correspondence, with the 6 statements in Objective-C paralleled by the 6 statements in AppleScriptObjC.
The main peculiarity is the use of possessive word forms and that variable attribution is done by using
"set X to Y" rather than
"X = Y". Type declaration is done via the idiom
'set <var> to <NSObject>'s <class init method>', which returns an instance of the object just as it would normally. You call instance methods by putting the instance in front of the method just as you would in regular Objective-C (e.g, see line 3 of the examples).
As you can see in the screenshot below showing Xcode and Script Editor, they work in the same way. You’ll notice in Script Editor there is a
'use' statement (equivalent to Objective-C’s ‘import’), and there’s also a whole load of property statements. These latter are peculiar to the ASObjC translation, and don’t have a counterpart in pure Objective-C. All you need to know about these is for each kind of Objective-C object you want to use (NSString, NSArray, whatever*), you’ll want a property statement for it at the beginning of the script. The statement always has the same form:
property <NSObject> : a reference to current application's < NSObject>
I think the best way to think of ASObjC was recently summed up by Sal Saghoian, when he said that ASObjC is “…the ultimate duct tape. You can do anything you want with ASObjC. You own the computer.”
*not all Cocoa frameworks nor all Objective-C objects can be bridged to, but pretty much all the most useful ones are available.
I recently discovered a neat little extra automation tool on top of the familiar ones of AppleScript, Automator, and script runners like FastScripts and Keyboard Maestro. Meet Hammerspoon, which differs significantly in not using Apple Events to do many of its automation tasks. Instead, Hammerspoon bridges directly to Apple APIs using the lua scripting language, and that allows you to do some interesting things.
Here’s a good example. One of the ‘danger zones’ on your mac – by which I mean one of the favourite places for adware, malware and other assorted badwares to infect – is your LaunchAgents folders. Apps like my DetectX and FastTasks 2 keep an eye on these areas by design, warning you in the Changes and History logs when files have been added or removed from them – but Hammerspoon can add an extra little ‘canary’ warning for you too. With only a few lines of code in Hammerspoon’s config file, you can set up an alert that will fire whenever the LaunchAgents folder is modified.
It has been possible to rig up something similar for a long time with Apple’s built-in Folder Actions, but there’s a couple of reasons why I prefer Hammerspoon for this task. One, despite Apple’s attempt to improve Folder Actions’ reliability, I’m still not convinced. I get inconsistent reports when asking System Events to check whether Folder Actions is enabled even on 10.11 and 10.12. Second, Folder Actions is limited in what it will respond to. By default, only if an item is added. With a bit of effort, you can rig it up to watch for items deleted, too, but that’s pretty much it. With Hammerspoon, it’ll alert you whenever the folder or its contents are modified in any way whatsoever. The final reason for preferring Hammerspoon for this particular task is ease of use. It really is as simple as pasting this code into the config file:
hs.alert.show("Launch Agents folder was modified")
hs.alert.show("Canary folder was modified")
local aWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/Library/LaunchAgents/", myFolderWatch):start()
local bWatcher = hs.pathwatcher.new(os.getenv("HOME") .. "/_Acanary/", canaryFolderWatch):start()
And what’s the config file you ask? Nothing complicated! Just launch Hammerspoon, click its icon and choose ‘open config’.
That will launch your default text editor, and all you do is paste your code into there, save it (no need to tell it where, Hammerspoon already knows) and then go back to the Hammerspoon icon and click ‘Reload config’. That’s it. Less than a minute’s work!
There’s a lot, lot more you can do with Hammerspoon, so if you’re interested head off and check out the Getting Started guide. One of the nice things is that you can even call AppleScripts with it, so you really do have a world of automation options to choose from!
I’ve been wondering ever since Yosemite what Apple had done to mess up Spotlight. It used to be my go-to way to launch apps. Faster than LaunchPad, the Dock or, of course, trawling through the Finder.
But something happened after Mavericks, and things have only being getting worse with Spotlight, right up to and including into Sierra.
Not only has Spotlight been slowed down with ads and ‘suggestions’, but we’ve also even lost the choice of re-ordering search results priority in Spotlight preferences.
I find Spotlight is not only slower than before, but it doesn’t always return the hit I want even when I know what I’m looking for. For a while, I got into the habit of searching using
locate in the Terminal. Like Spotlight, these use an index based search so can return results very fast. Eventually, I got fed up of that, and wrote my own search tool and added it to FastTasks 2
All this is not good, and if you are seeing the same degradation in Spotlight’s usefulness as I have been, try unchecking the following Preferences and see if it works to get Spotlight back up to a useful speed. With these disabled, I’ve seen a remarkable improvement in Spotlight in macOS 10.11.6.
I tend to work on the iMac at home, then take an MBP to work. Several times I’ve thought iCloud had uploaded what I had been working on at home before I left, only to find that when I got to work, the old version was still the latest one on iCloud. Of course, I checked for the spinning little progress indicator, but apparently I either missed it or it didn’t appear.
To mitigate this problem, I came up with this script to tell me what iCloud daemon is doing. If files are pending update or being updated, it will indicate which ones. It will also tell me if the iCloud daemon is either idle or busy / not responding.
Last week I was asked whether I could produce a script that would keep track of Carbon Copy Cloner backup tasks so that a user could tell which of many, multiple backups of the same source disks were the most recent.
Of course, CCC has its own Task History and Disk Center functions to provide information, but these turn out to be insufficient in common scenarios. To see why, let’s consider a hypothetical task set-up and recovery situation.
In this situation, let’s suppose I’m keeping 2-hourly, daily and weekly clones of my mac’s internal disk. While I’m logged in to my mac, I can of course check CCC’s Task History to see when the last back up was, the destination, and whether it was successful or not.
However, suppose the internal disk fails – just the situation for which I keep my CCC backups on a regular schedule. Which disk contains my latest backup? The information from CCC’s history task is on the failed internal disk, so it is not now available to me. Of course, each backup contains CCC’s earlier History too, but there’s several problems here. First, these cloned task histories do not contain the history from the *last* task (that’s only written to the source disk after the last backup completes). Second, to compare them, I’d have to boot each clone individually – a time-consuming and not terribly convenient process. Third, CCC’s ‘Disk Center’ only provides backup information about connected disks if the current startup disk was used to run the backup task. Thus, if I backup Disk B from Disk C, that information won’t be available to me when I startup my mac with Disk A.
Before I discuss the solution to this, let me just complicate the scenario further. I have two other macs – two 13″ MacBook Pros that have been going strong since 2009 – each of which I backup to individual clones. There’s no way for me to see all the backup dates from all my macs with CCC. Further, we don’t need to consider only disk failure as a reason to need comparative backup history. Since some files are shared or swapped across my three macs, there’s no way to find out from CCC’s Task History or Disk Center when the latest backup of any particular one of those files was made, or on which backup disk I can find it. For example, the connected disk ‘MBP Z Clone’ is a scheduled task on my MBP, but looking at this disk when connected to my iMac gives me no information about its backup history:
Fortunately, CCC has two features which make our problems solvable. First, each source disk keeps detailed logs of the backups it has run (from which the Task History and Disk Center info is constructed); secondly, CCC allows us to run a shell script after each task has completed.
These two little features are going to allow us to build a shell script that will write a special log file to the destination after each task completes, and then retrieve it and compare it against both the current source and other disks. That means we’ll be able to get CCC backup data from any disk we connect to any mac, since the data will be stored on the destination disk itself thanks to our shell script (for the technically minded: to avoid permissions problems, the script writes to /Users/Shared/ if it’s a bootable clone, or to the root of a disk that isn’t).
That’s the outline of the problem and the solution. What started out as a simple AppleScripting task soon blossomed into a full-blown app. Although much of the background work I’ve outlined above is achievable via AppleScript, displaying the data effectively is rather cludgy, even if one uses some of the excellent scripting libraries like Shane Stanley’s ‘Myriad Tables’ to improve on the stock AppleScript offerings.
Accordingly, after about a week or so of wrestling with an acceptable solution, I finally came up with the Disk Inspector.app to solve all these problems in one go and add a few niceties on top. 😉
Whatismore, since it’s Christmas :D, I’m publishing this as a free utility on my software site, Sqwarq.com. Check out Disk Inspector’s support and download page here: https://sqwarq.com/disk-inspector
Here’s a quick overview of the main features:
1. See dates of all connected disks that have been backed up via CCC*
2. See the latest backup and (if available) Time Machine backup for the current source disk
3. See the OS Version and Build Number on connected, bootable drives
4. Open any disk’s root folder in the Finder by double-clicking its name in DI’s main view
5. See an estimate of the total and available space on each disk (rounded to the nearest GB)
6. Save all the data to a log file for easy record keeping of your backups
* after completing Disk Inspector’s set up procedure
For full instructions refer to the Support page, but the basic idea is that on first launch, you run the ‘Set Up’ wizard to configure your tasks in Carbon Copy Cloner. Disk Inspector’s ‘Set Up’ wizard walks you through 5 simple steps to accomplish all this.
Once you’ve completed the set up procedure and each of your scheduled CCC tasks has run, you’ll start to see information for each backup disk in Disk Inspector’s main view on any mac (or on the same mac booted from a different drive) that you subsequently connect those disks to.
Disk Inspector runs on 10.10 and higher.
Enjoy, and Happy holidays to all! 😀
DetectX has been updated today to v2.37, and amongst other changes now detects and removes iDoctor.app. This piece of software appears to be another MacKeeper clone, with both sharing a common interface, code and file structures.
In the screenshot above, you can see DetectX doing its work – note the parallel file detections as DetectX hunts down both MacKeeper and iDoctor.
Below is a sidebar shot of MacKeeper on the left and iDoctor on the right. Underneath that are shots showing how the two interfaces are almost direct mirrors of each other. It’s hard to believe these are not both being built from the same base code, and we strongly suspect that the developers of iDoctor are very likely the same developers of MacKeeper, or at least real close friends!
This little tool will help you keep track of when Apple make changes to system config data like XProtect, Gatekeeper and the Malware Removal Tool. It will also alert you if there is a Security update in the App Store that needs to be manually applied.
Critical Updates is free for home use. Organisations wishing to license it for commercial-scale use should contact me through Sqwarq support.
I’ve not been very happy with Apple this week. Not only are they mistreating developers, but they’re also mistreating their customers.
If you have chosen not to upgrade to Sierra for some reason, but your mac is both compatible and has enough disk space for the Sierra download, Apple’s servers may download the entire 5GB Sierra installer to your machine without asking you for permission first.
If you have data caps, or are on a plan that offers differential pricing depending on time of use, this could totally ruin your month.
If you want to ensure that Sierra does not silently download to your mac, you’ll need to uncheck the ‘Download newly available updates in the background’ option in App Store’s Preferences pane in System Preferences (see image above).
Who knew by ‘updates’ that Apple were going to include upgrades of 5GB when they ticked that box? Well, now you do!
Unfortunately, your decision not to upgrade to Sierra won’t stop Apple infecting your machine with it’s own little adware notification, and you’re likely to see this at some point or another:
Note that there is no option to say “Don’t remind me again”, so there’s no telling how often you’ll be irritated with this unwanted pop-up.
Hmm, whatever happened to old-fashioned good manners, aye Apple? 😉
The recent update to Script Debugger 6 added a subtle, but much-needed new feature.
Now, scripters can take advantage of the same kind of navigation markers familiar to users of Xcode (pragma marks) to quickly navigate to user-defined sections of the script.
Scripters can now create a marker with a double-dash and double arrow marker, followed by whatever label they choose.
-->> myMarker here!
For me, this is a great boon, and I’ve changed all the section headings in my templates to the new navigation marker syntax, meaning I can easily jump to the various sections from the Navigation bar at the top of the script.
Script Debugger 6: The Complete Review