Quick Actions 4: How they work

Until two and a half years ago, it wasn’t particularly clear how modern macOS app extensions (‘actions’ and their ilk, not kernel extensions) worked. Apple’s documentation, first published in 2014, explained quite well how to develop different types of extension, but has never been updated to cover Mojave’s Quick Actions, and doesn’t tackle how an ‘Action’ extension works with respect to macOS sub-systems.

Then in July 2016, shortly before the release of macOS Sierra, Aditya Vaidyam took its private frameworks apart and revealed how Sierra handles extensions. Sadly I have been unable to discover any more recent study which provides comparable detail, so combine the information which he has published with my own explorations using Mojave’s unified log.

At the heart of the Mojave extension sub-system is the management daemon pkd, which is a LaunchAgent within macOS, and first appeared in 10.9. In the log, it appears in its own right as pkd, and as part of the com.apple.pluginkit sub-system. Because extensions, particularly Quick Actions, all happen in userland, there is only one copy of pkd running at a time, owned by the current user.

pkd and the whole sub-system can be interrogated using the pluginkit command, which can be used with its -a or -r options to change the extension database managed by pkd. Because pkd manages this automatically, it will eventually add back any extensions which you might have removed manually, for instance, limiting pluginkit‘s usefulness.

pkd scans installed apps and other software for eligible extension bundles; when it finds one, it analyses it and makes it available for use. When you use the Finder’s contextual menu, which contains sub-menus of different types of extension, including Quick Actions, pkd performs a series of ‘discovery’ scans to populate those sub-menus.

For example, here is the sequence which adds four plugins or extensions for Quick Actions from recognised apps. I use [] to mark edited sections, for the sake of brevity.
27.877881 com.apple.sharekit Framework Finder ShareKit Discover <private>
27.877894 Finder PlugInKit discovery
27.879026 com.apple.PlugInKit ops pkd pkd plugin /Applications/Pixelmator.app/Contents/PlugIns/Repair Tool Action Extension.appex is still valid.
27.879062 com.apple.PlugInKit ops pkd pkd plugin /Applications/Attributed String Creator.app/Contents/PlugIns/Attributed String Creator Extension.appex is still valid.
27.879090 com.apple.PlugInKit ops pkd pkd plugin /Applications/Wrise.app/Contents/PlugIns/SelectionReader.appex is still valid.
27.879118 com.apple.PlugInKit ops pkd pkd plugin /System/Library/PrivateFrameworks/MarkupUI.framework/PlugIns/Markup.appex is still valid.
27.879234 com.apple.PlugInKit ops pkd pkd Candidate plugin count: 4, info: ("com.assistiveware.wrise.selectionreader(1.4) 8F59D5E0-548F-4F4C-95A4-9D18F2725A31", [])
27.879956 com.apple.PlugInKit ops pkd pkd Resulting plugin count: 4, UUIDs: ("8F59D5E0-548F-4F4C-95A4-9D18F2725A31", [])
27.880387 com.apple.sharekit Framework Finder ShareKit discovery complete: 4 plugins
27.880708 com.apple.sharekit Framework Finder ShareKit Discover done

Note that extensions/plugins are recognised by assigned UUIDs.

Four bundled Quick Actions are given special treatment:
27.890345 com.apple.PlugInKit ops pkd pkd plugin /System/Library/CoreServices/Finder.app/Contents/PlugIns/PlaceholderTrim.appex is still valid.
27.890388 com.apple.PlugInKit ops pkd pkd plugin /System/Library/CoreServices/Finder.app/Contents/PlugIns/PlaceholderCreatePDF.appex is still valid.
27.890413 com.apple.PlugInKit ops pkd pkd plugin /System/Library/CoreServices/Finder.app/Contents/PlugIns/PlaceholderMarkUp.appex is still valid.
27.890438 com.apple.PlugInKit ops pkd pkd plugin /System/Library/CoreServices/Finder.app/Contents/PlugIns/PlaceholderRotate.appex is still valid.

Calling one of the bundled Quick Actions is also very different from a user-created Automator workflow. Bundled Quick Actions are processed very quickly, with a minimum of log entries, most from Foundation’s filecoordination, and followed by QuickLook generation of a new thumbnail for the document. Here’s an example of the Rotate Quick Action, in which [UUID] represents the same UUID known as the claimID:
00.473418 com.apple.foundation.filecoordination claims Finder Foundation Read options: 0 -- URL: <private> -- purposeID: com.apple.finder.quickaction.rotate7D178CB6-2C19-4E28-A626-8F1DEE0105D9 -- claimID: [UUID]
00.473604 com.apple.foundation.filecoordination claims filecoordinationd Foundation Received claim [UUID]
00.473634 com.apple.foundation.filecoordination claims filecoordinationd Foundation Claim [UUID] granted in server
00.473753 com.apple.foundation.filecoordination claims filecoordinationd Foundation Claim [UUID] invoked in server
00.473808 com.apple.foundation.filecoordination claims Finder Foundation Claim [UUID] granted in client
00.473810 com.apple.foundation.filecoordination claims Finder Foundation Claim [UUID] invoked in client
00.477299 com.apple.foundation.filecoordination claims filecoordinationd Foundation Claim [UUID] was revoked
00.477304 com.apple.foundation.filecoordination claims filecoordinationd Foundation Claim [UUID] was devalued
00.509979 com.apple.quicklook Request qlmanage QuickLook Thumbnailing <private>. Content type UTI: public.jpeg. Generator used: <private>
00.512084 com.apple.quicklook Request qlmanage QuickLook Thumbnailing <private>. Content type UTI: public.jpeg. Generator used: <private>

Running a Quick Action workflow is much more complex, and involves WorkflowServiceRunner and com.apple.automator.runner which actually host the workflow. What’s more, instead of using Foundation filecoordination as shown above, the work is largely performed by com.apple.launchservices. Automator workflows don’t appear to be subject to the same discovery process by pkd either, and I suspect fall outside pluginkit‘s controls as well.

Extensions/plugins compiled using Xcode and delivered as part of an app bundle are thus very different from those generated using Automator. This is an important distinction when trying to troubleshoot problems with Quick Actions.