Hi,
I am trying to develop MacOS application which will be connecting to USB devices and should be available in AppStore.
So it must be Sandbox and probably I've to use permission com.apple.security.device.usb
.
I've following requirements:
- I need to detect USB devices with file system
- I need to have ability to upload & download files from this device
- I need to read device serial number
I wonder if I can use IOKit for this and it will be compliant with AppStore rules or not?
I saw they are using IOKit somehow, but I'm not sure it is used for this.
So, the first thing to understand here is that IOKit is basically THE API here. Other frameworks are often built on top/around it (more on that shortly), but IOKit is the core of how hardware is discovered and accessed from user space.
Case in point:
For generic Kindle, right now we are using system_profiler SPUSBDataType -xml for detection
Basically "all" of the hardware specific information you see in system_profiler was actually pulled from the IORegistry using IOKit. A few things I'd recommend when you're getting started with IOKit:
-
Take a close look at the documents "IOKit Fundamentals". This is document is the "base" reference for how IOKit (the kernel API) is structured and functions and will help you understand what you're seeing on a "real world" system.
-
Download and experiment with "IORegistryExplorer.app", which you'll find in side the "Additional Tools for Xcode <version>". Note that while that download is versioned to Xcode, you don't really need to worry about staying "current". IORegistryExplorer.app itself changes VERY little- the app itself is 24+ years old but is only at v3.0.2 and I don't think it's been updated since 2013. In any case, what IORegistryExplorer.app actually shows you is the system "IORegistry" structure, which is the core of how IOKit hardware discovery and communication works. Note that the data you're actually seeing in SPUSBDataType call came from the IORegistry data store.
-
Read "Accessing Hardware From Applications", which is the reference for using the IOKit (user space) API to interact with hardware. It describes how you'll actually discover hardware and retrieve information about it.
I would be happy to hear if you have a recommendation for APIs
In terms of the API side of this, the basic approach would be:
-
Use IOKit to discover existing devices and monitor for new ones, then determine whether your app should interact with them based on the devices properties. You can find some basic code in this post showing what this looks like. Note that it is ONLY a simple starting point. For example, it uses "IOServiceGetMatchingServices" (which searches for registry) but an app would use "IOServiceAddMatchingNotification" (which finds current services and then monitors for new ones).
-
Based on the serial number (retrieved in #1), you'd then either use file systems access or device access.
-
The file system access operates entirely outside of IOKit. IOKit (and other APIs) can be used to determine what mount point corresponds to a particular hardware device but all of the actual "access" would be handled just like any other file access.
-
For MTP access, the IOKit object from #1 would then be used to directly communicate with the device through the IOUSBHost framework. Note that while the framework uses the term
"host-mode user space drivers",
that is a very fancy way of saying "an app that directly controls device".
that are compatible with AppStore's policy.
In terms of sandbox compatibility, I think the "com.apple.security.device.usb" entitlement is the main one you'd need. What's allowed on the App Store is ultimately determined by App Review, but I don't think any thing I've described above would be an issue on the App Store.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware