Cocoa

In an effort to support macOS Monterey’s new Shortcuts in Transloader‘s Link– and File Actions, I decided to run all the necessary CLI commands and AppleScripts in an external XPC service, mostly to separate privileges (running Apple Scripts (which aren’t precompiled and reside in the Application Scripts folder) in a sandboxed Mac app requires specific sandbox entitlements, which Transloader itself just doesn’t need).

I didn’t start with an XPC service, though. For testing and debugging purposes, I began with a new app in Xcode and ran all the Apple Scripts from there, which, after a bit of tweaking because I’m not “fluent” in Apple Script, worked just fine.

After subsequently moving them into an XPC service and thinking it would “just work”, I found that it didn’t. At least not reliably. Maybe every 8th or 9th time, yes, it did all it was asked to do, but every other time, it outright refused to execute Apple Scripts.

After two days of desperate attempts to get it working correctly, and almost giving up on the XPC privilege separation entirely for this, I figured I’d check to see if the Apple Scripts were being executed on the main thread.
I did recall reading quite some time ago (I don’t know where, sorry) that Apple Scripts on background threads are iffy in their execution. Lo and behold, the methods weren’t run on the main thread. One quick dispatch_async to the main queue later, and everything worked as I expected it to.

So, the takeaway of all this, and the TLDR, is this post’s title: An XPC service’s methods aren’t necessarily run on the main thread. Go figure.

Addendum

If you’re wondering what my configuration for the XPC service is:

RunLoop = NSRunLoop
ServiceType = Application

I did try dispatch_main as RunLoop as well, which worked too, but I just figured, for Apple Scripts, NSRunLoop would be required, but I don’t know for sure.

Read more

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:

Screenshot the sample project's source code

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! 😊

Read more