screencapture and the Sandbox in macOS Sierra (Updated)

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:

Sandbox Violation of ScreenFloat on macOS SierraThe 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:

ERROR ITMS-90285

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.

 

Eternal Storms Software Logo

– – – 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 :)