ZMIOUSB is a framework that bridges IOKit USB APIs to Swift.
- Requirements: OS X 10.9 or later
- Swift version: 4.0
To install this framework using Carthage, add the following line to your Cartfile.
github "zumuya/ZMIOUSB"
let deviceInterface = try USBDeviceInterface.create(vendorIdentifier: VENDOR_ID, productIdentifier: PRODUCT_ID)
defer { deviceInterface.release() }
let interfaceInterface = try deviceInterface.createInterfaceInterface()
defer { interfaceInterface.release() }If you create interfaces, you must call release() after using them. We recommend to use defer {} since many functions in this framework throw errors.
try deviceInterface.openAndPerform {
...
}
try interfaceInterface.openAndPerform {
...
}try interfaceInterface.write(someData, pipe: PIPE_WRITE)let result = try interfaceInterface.readBytes(pipe: PIPE_READ)DispatchQueue.global().async {
do {
let deviceInterface = try USBDeviceInterface.create(vendorIdentifier: VENDOR_ID, productIdentifier: PRODUCT_ID)
defer { deviceInterface.release() }
let interfaceInterface = try deviceInterface.createInterfaceInterface()
defer { interfaceInterface.release() }
try interfaceInterface.openAndPerform {
try interfaceInterface.write([0x01, 0x02, 0x03], pipe: PIPE_WRITE)
let result = try interfaceInterface.readBytes(minCount: 16, pipe: PIPE_READ)
DispatchQueue.main.async {
self.displayText("Received: " + result.description)
}
}
} catch let error {
DispatchQueue.main.async {
self.presentError(error)
}
}
}Use USBDeviceInterface.observeDeviceList(...) to get callbacks when USB devices are connected or disconnected.
let observer = try USBDeviceInterface.observeDeviceList(vendorIdentifier: VENDOR_ID, productIdentifier: PRODUCT_ID) { (notification, service) in
do {
switch notification {
case kIOFirstMatchNotification:
print("device is connected!")
let deviceInterface = try USBDeviceInterface.create(service: service)
defer { deviceInterface.release() }
...
case kIOTerminatedNotification:
print("device is disconnected!")
...
default:
break
}
} catch let error {
print("error: \(error)")
}
}
self.deviceListObserver = observer //keep it!Since this framework just extends original types, you can use original APIs without casting.
let ioReturn = interfaceInterface.pointee?.pointee.ResetPipe(interfaceInterface, 1)This framework extends IOReturn with LocalizedError protocol.
You can throw an IOReturn as a Swift error.
let ioReturn = interfaceInterface.pointee?.pointee.ResetPipe(interfaceInterface, 1)
if (ioReturn != .success) {
throw ioReturn
}By using IOReturn.throwIfNotSuccess() method, you can call existing functions with try keyword.
try interfaceInterface.pointee?.pointee.ResetPipe(interfaceInterface, 1).throwIfNotSuccess()This framework doesn't contain any localization for error messages. But you can provide and customize messages.
IOReturn.errorDescriptionHandlers.append { error in
NSLocalizedString(String(format: "IOReturn_description_%i", error.rawValue), comment: "")
}
IOReturn.recoverySuggestionHandlers.append { error in
NSLocalizedString(String(format: "IOReturn_recoverySuggestion_%i", error.rawValue), comment: "")
}This framework is distributed under the terms of the MIT License.