In my app ScreenFloat, I use the command line tool screencapture via NSTask to create screenshots. On OS X El Capitan and earlier versions of Apple’s operating system, this worked perfectly fine. Now, on macOS Sierra, I’ve been getting reports that screenshot creation didn’t work anymore, so I investigated.
At first I thought it might be the keyboard shortcut API that has undergone some changes, but that doesn’t seem to be the case, as I saw something actually occurred when I pressed the keyboard shortcut – Xcode’s console printed:
screencapture: cannot run two interactive screen captures at a time
Since I was absolutely sure I’m not launching screencapture via NSTasktwice, I took to Console.app to see if anything unusual was reported there. And there it was:
The output in Console.app when trying to launch an interactive screencapture with NSTask.
deny mach-register
So registering a global Mach service is denied on macOS Sierra. In the back of my mind, I remembered a temporary exception entitlement, but it wasn’t quite the same – com.apple.security.temporary-exception.mach-lookup.global-name. I tried adding it to ScreenFloat’s entitlements file, with com.apple.screencapture.interactive as its value (this temporary entitlement expects an array of string values), but that didn’t help – the same denial and console output occurred. On a hunch, I tried using …mach-register.global-name instead of …mach-lookup.global-name and – tada – it worked!
So I’m all set, right? Well…
Temporary Exception Entitlements
Apple offers a couple of temporary exception entitlements. They may or may not be granted to your app during Apple’s review process. But going through the list, it’s clear that …mach-register.global-name is nowhere to be found, so it’s kind of a private entitlement – which makes it even less likely for it to be granted to your app.
Digging Further
Seeing as the sandbox denial points explicitly to com.apple.screencapture.interactive, not just com.apple.screencapture generally, I tried creating a non-interactive screencapture session with NSTask. To my surprise, it worked – without the entitlement.
So I tried a different command line utility – which. (which will return the executable path to the given command line utility, for example, which screencapture would return /usr/sbin/screencapture). Again, it worked. And again, without the entitlement.
It makes me believe (and hope) that the behavior we see for com.apple.screencapture.interactive is not desired, so I’ve filed a bug report with Apple in the hopes that they can set the record straight soon.
For now, I hope ScreenFloat will be granted the temporary entitlement just so it is functional again on macOS Sierra for the time being. However, if this is in fact the desired behavior, I will have to write my own screencapture utility so ScreenFloat can remain on the Mac App Store.
Bug Reporting
For anyone who’s interested or in a position to view it, here’s the bug report I’ve filed with Apple: rdar://27610157. I do hope to get an answer soon.
Update August 2nd, 2016
As I stated above, com.apple.security.temporary-exception.mach-register.global-name isn’t documented anywhere. Which is also the reason you get an error when trying to submit an app with such an entitlement to iTunes Connect:
So, no dice on the temporary exception. Having to write my own screenshot utility seems more and more likely. I hope I can make it in time for macOS Sierra.
Update September 9th, 2016
The temporary exception is now valid and will go through to Apple’s App Review without a hitch. My own solution is not necessary at this time, but I’m still going to be working on it – you never know.
– – – Do you enjoy my blog and/or my software? – – –
Stay up-to-date on all things Eternal Storms Software and join my low-frequency newsletter (one mail a month at most). Thank you 🙂