I’m prototyping a personal-use system that lets an iPhone with a physically attached controller act as an input device for a Mac.
End goal:
- Use the iPhone as the transport and sensor host
- Use the attached physical controller for buttons/sticks
- Map the iPhone gyroscope to the controller’s right stick to get gyro aim in Mac games / cloud-streamed games such as GeForce NOW that don't support the gyro.
What I’m trying to understand is whether Apple supports any path for this on macOS that does NOT require restricted entitlements or paid-program-only capabilities.
What I’ve already found:
- CoreHID virtual HID device creation appears to require
com.apple.developer.hid.virtual.device - HIDDriverKit / system extensions appear to require Apple-granted entitlements as well
- GCVirtualController does not seem to solve the problem because I need a controller-visible device that other apps can see, not just controls inside my own app
So my concrete question is:
Is there any supported, entitlement-free way for a personal macOS app to expose a game-controller-like input device that other apps can consume system-wide?
If not, is the official answer that this class of solution necessarily requires one of:
- CoreHID with restricted entitlement
- HIDDriverKit/system extension entitlement
- some other Apple-approved framework or program I’m missing
I’m not asking about App Store distribution. This is primarily for local/personal use during development. I’m trying to understand the supported platform boundary before investing further.
Any guidance on the recommended architecture for this use case would be appreciated.
What I’m trying to understand is whether Apple supports any path for this on macOS that does NOT require restricted entitlements or paid-program-only capabilities.
So, let me lay out the state of things that you listed:
-
Both DriverKit and Core HID require restricted entitlements.
-
All DriverKit entitlements have "Development Only" variants which allow those entitlements to be used in development signed builds without any approval (they're added through the portal like any other entitlement).
-
Virtual Core HID does not currently have a development variant, but that's an issue I'm looking into correcting (r.173531752).
In both cases, that means using these entitlements currently requires joining the paid program. If you'd like to see us expand these to the free account as well, please file a bug asking for that and then post the bug number back here. Also, to be clear, that is a serious request - I'd like to look at expanding the availability of these entitlements, but that's hard to justify without a bit showing that "someone" actually wants us to expand entitlement availability.
Any guidance on the recommended architecture for this use case would be appreciated.
Those two APIs are the only options that will allow you to create a "true" HID device that can replicate the same capabilities a physical controller does. Choosing between those two APIs, I would STRONGLY recommend Core HID over DriverKit. It's a standard user space API, which makes it FAR easier to use than DriverKit. There are a number of products available that use DriverKit for this and, to be honest, I have no idea why they work this way.
Is there any supported, entitlement-free way for a personal macOS app to expose a game-controller-like input device that other apps can consume system-wide?
First, as background context, the entitlement requirement is intentional, as virtual HID devices can be used to create a variety of attacks against the system.
In any case, there are basically two other options here:
-
Reduce system security and use the entitlements. This isn't really an approach I'd recommend, but if you disable SIP and AMFI, then that would let you use either of the entitlements above. Disabling SIP/AMFI has very serious security implications, but if you want to use this approach, then Quinn has a forum post describing what's required.
-
Use CGEventTap to inject events directly into the event system.
Expanding on that second approach, you're basically injecting events into the layer that converts HID level commands into the events actually received and processed. That limits the kind of activity you can generate (basically, you can generate keystroke and/or move the mouse), but aside from that, you can fully "control" the computer. If you've ever wondered how Apple Remote Desktop moves the mouse on a remote machine, event tap is the answer.
How well #2 works depends entirely on what you want to do. On the plus side, it will work "anywhere" since, as far as the system is concerned, the mouse is just moving the way it always does. On the other hand, if you're specifically trying to work the games that provide true Game Pad support, then it won't work nearly as well as a HID-based solution would.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware