Mac Developer Tip: How to get Remote Notifications Working Again (If They Suddenly Aren’t)
Yesterday, I was working on Transloader v3.0. In particular, on its push notifications and making sure everything syncs properly.
Today, I wanted to continue working on this, but found myself unable to. My Mac suddenly didn’t receive CloudKit push notifications anymore.
Even worse, neither of the delegate methods
- (void)application:(NSApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
and
- (void)application:(NSApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
weren’t called anymore – without any code changes. Something was wrong.
But here we are, a couple of hours later, and everything’s working again. Finally.
So, to save you some time should this happen to you, here’s what I did:
Restart
I restarted my Mac – the obvious solution. You might think. Only that it didn’t work, the problem persisted. But it’s still the first thing I’ll try if this returns.
Delete Containers, Group Containers, and CloudKit Caches
In Finder, delete
/Users/yourname/Library/Containers/yourAppContainerFolder/
/Users/yourname/Library/Group Containers/yourGroupID.yourAppGroupContainerFolder/
/Users/yourname/Library/Caches/CloudKit/yourAppID
/Users/yourname/Library/Caches/CloudKit/CloudKitMetadata* (*all files that begin with that filename)
/Users/yourname/Library/Caches/CloudKit/CloudKitOperationInfo* (*all files that begin with that filename)
Now launch Activity Monitor.app and force quit the following processes:
cfprefsd
apsd
notifyd
remoted
Now, I’m not sure you need to force-quit each and every one of those, but I wanted to relaunch any process that remotely looked like it had to do with remote/push notifications.
At this point, I restarted Transloader through Xcode, and lo and behold, it worked again.
On my MacBook Pro, where the same problem occurred simultaneously, I took the same steps. And it *didn’t* work. A restart was required, so your mileage – like mine – may vary.
Additional Info
There’s also this handy technical note from Apple, which can help debugging push notifications on both macOS and iOS.
Open Source [macOS] – NSMenuItems with Subtitles
For Transloader’s upcoming version 3.0, I needed an NSMenuItem that not only showed a title, but also a subtitle, along with an optional image.
Because it took a bit of work and “reverse-engineering” (the click-on-an-item-selection-animation’s timing, in particular), I figured someone else might benefit from this.
Where to get it / Sample Project
It’s all pretty straight forward, and best shown / explained as an Xcode project, which you can download on Github.
This is basically all you need to do:
That’s it!
Caveats
There are some things this implementation can not do, which the default NSMenuItem can:
- There is no type select
- The arrow keys can’t be used to go through the items
- You can’t activate items with the space or enter keys
Basically, keyboard interaction is unavailable.
I do hope it’s useful to you anyways.
If you’re using this, I’d love to hear from you! 😊
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:
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 🙂