Software

In an effort to show preferences for configuring Force Touch in my apps (in particular, Yoink) only when a Force Touch device is actually available, I had to find a way to figure out how to detect Force Touch devices.

If this was iOS, I’d be done by now

On iOS, Apple provides a simple API for this:

UIForceTouchCapabilityUnavailable and UIForceTouchCapabilityAvailable

which you can check by calling UIView’s – (UIForceTouchCapability)traitCollection;. Lo and behold, a simple API like this is sadly not available on OS X. On the Mac, you have to do it yourself.

IOKit is where it’s at

Using IOKit, you can sort of set up a set of properties you’re looking for in a device and see if it returns anything. This does not only include an external or internal keyboard, mouse or trackpad, but also graphic cards, for example. To find out what the right properties are, I downloaded Apple’s Hardware IO Tools for Xcode 7.1 from their developer downloads site (Apple Developer account required) and launched the app IORegistryExplorer.

Digging down the IO Registry

I do have a Magic Trackpad 2 “attached” to my Mac via Bluetooth, so I tried searching for the term “Trackpad”, and sure enough, I saw my internal and external ones:

IORegistry TrackpadsThe Trackpads attached to my Mac, either via Bluetooth or internally.

Having found the Magic Trackpad 2, the next step is to see what properties it offers and if they are unique to the class of the device:

Trackpad PropertiesJackpot!

Sure enough, there it is – ForceSupported: True. I could not find such a key in the internal trackpad’s properties, hinting that it might be exclusive to devices that do support Force Touch. There’s also an entry for “Manufacturer”, which is “Apple Inc.”. Perfect.

Looking for Devices with IOKit

Now all I have to do is filtering devices by the Manufacturer – “Apple Inc.” -, iterate over the resulting devices, and filter out devices that have a DefaultMultitouchProperties key, containing a ForceSupported key with a value of true. If such a device is found, it means a device with Force Touch capabilities is available.

Code Listing #1

In this method, I create a dictionary mDict that is used to find matching devices. In this case, I’m looking for devices with the Manufacturer set to “Apple Inc.”. I query for possible devices using IOServiceGetMatchingServices. I can then iterate over the returned io_iterator_t iterator and recursively over the children in the core of all of this: – (BOOL)_containsForceTouchDevice:io_iterator_t)iterator;.

Code Listing #2

Here, we iterate recursively over iterator’s objects, checking for the DefaultMultitouchProperties key and, subsequently the ForceSupported key (and value).

Testing it with other Trackpads

The code you see above is final. However, in a previous version, all I could use to test it with was my Magic Trackpad 2 – an internal Force Touch Trackpad (the likes of which the new MacBooks and MacBook Pros feature) was not available to me directly. So I sent the first draft of the code to my friend (and fellow developer) Maurice Kelly (@mauricerkelly on twitter) who was kind enough to volunteer as my “test subject”; and – of course – it didn’t work. Turns out I shouldn’t assume the vendorID to be the same (which I used in the first draft just like the Manufacturer to filter the possible results). After leaving it out, it worked fine over all currently available Force Touch Trackpads.

Hot (Un-)Plugging

Sometimes you might want to get notified when devices are plugged in to or unplugged from the Mac. In Yoink, I’d like to display preferences specific to Force Touch if according hardware is available, but not show them if there isn’t any hardware connected that supports it. Also, as a nice touch, I’d like to hide the preferences if according hardware is disconnected and show it again when it is connected. We can accomplish this like that:

Code Listing #3

Sandbox

The code works just as well in the Sandbox environment, these entitlements have to be set, though, for the notifications to work:

Sandbox Entitlements

com.apple.security.device.usb and com.apple.security.device.bluetooth

Future Proof?

I’m not sure this code is future proof. The basic APIs will stay around, sure, but it all depends on the keys DefaultMultitouchProperties, ForceSupported and their according values which are not defined in the IOKit header files, which I unsuccessfully searched for constants pertaining to force/pressure. So, depending on this, the code might break with future versions of the Force Touch Trackpad and I’ll have to keep testing it as Apple releases new hardware. Nevertheless, I’m quite happy with the code and it works very well.

Getting the Source Code

I’ve uploaded a sample project to my server, you can download it here. The category on NSApplication in which this is available can be downloaded from Github. The example app is pretty simple:

Force Touch Device Detection Example App Screenshot

At launch, it asks if a Force Touch capable device is available and displays an according message. If subsequently the availability status changes, the message will be updated accordingly.

If you’d like to get in touch, you can mail me or write me on twitter. I’m looking forward to hearing from you 🙂

Read more

OS X 10.11 El Capitan

I’m happy to say that all my applications, Yoink, Glimpses, ScreenFloat, Transloader and flickery are compatible with OS X 10.11 “El Capitan” and work perfectly on Apple’s new operating system, which will be released tomorrow, September 30th.

I’ve tested all my apps on the Golden Master of the upcoming Mac system upgrade and haven’t found any showstoppers or issues.

Should you, however, discover anything you feel is a bug, an annoyance or an issue, please be sure to get in touch with me either by mail, twitter or Facebook – I highly appreciate your help.

I hope you’ll enjoy tomorrows upgrade of OS X, I know I am very much looking forward to it!

Read more

Yoink for Mac Usage Tip #8

The following explains how to add attachments directly from Mail.app into Yoink.
For more Usage Tips like this, click here.

Today, I received an eMail from Sandro G. asking me if there was a way to quickly add mail attachments from selected mails in Mail.app to Yoink.

The Problem

Sandro frequently adds attachments from mail messages in Mail.app to Yoink but says it can be cumbersome with lots of mails with a couple of attachments each.
I agree, having to select each mail message with an attachment, scrolling down and dragging each attachment to Yoink can take a lot of time.
Instead, he says, he’d like a way to just select the mail messages that contain the attachments, ideally press a keyboard shortcut and let Yoink do the rest, saving nerves and, most importantly of all, time.

The Solution

As with the “capture screenshots to Yoink”-problem, where Bogdan V. wanted to be able to take screenshots that automatically end up in Yoink, Automator seemed like a good solution for this.

I launched Automator and created a System Service – easily accomplished by creating a new project and selecting Service in the resulting dialog.
A system service is something you can either access through a contextual menu or by the applications Application menu -> Services, containing context-aware services, for example “Look up in Dictionary” or “New Email with Selection”.

Automator - New Project DialogAutomator’s New Project Dialog. Select Service and click on Choose.

The Automator Workflow

Automator - Finished workflowThe finished workflow.

Let’s go through it from the top. Specify the service to receive no input (as the other possible values don’t apply) and select Mail as the target application the Service should be available in.
Now we need three actions:

  1. Get Selected Mail Messages – creates a reference to the currently selected mails in Mail.app
  2. Get Attachments from Mail Messages – uses the references created before and saves their attachments to a folder, in this case the Default Mail downloads folder
  3. Open Finder Items – Action 2 passes the attachment files to this action, where we ask Yoink to open those files, resulting in them being added to Yoink’s files

Installation and Keyboard Shortcut

Once you save it, it should be automatically saved into your Services folder. If not, double-click the saved file and it should prompt you with this dialog – click Install and it should be installed correctly:
Automator - Service Installation
If you’d like a keyboard shortcut, it’s quickly done. Launch System Preferences, select Keyboard -> Shortcuts -> Services, scroll to find the service and set up your shortcut:
Service - Keyboard Shortcut
Now you can access the service either through this keyboard shortcut or the Services menu in Mail.app’s Mail menu:
Service Installed in Mail

Automator Workflow Download

For your convenience, here’s the workflow ready for download.
Unzip, double-click to install. Set up the optional keyboard shortcut – done 🙂
If you have any feedback, questions or improvements, please be sure to get in touch – by mail or twitter – I’m looking forward to hearing from you!
Read more