if let ps = IOHIDDeviceGetProperty(self.device, "Product" as CFString) as? String
{
debugLog("Product: \(ps)")
}
Expecting IOHIDDeviceGetProperty() to return a UTF-16-encoded CFStringRef. But I think Swift assumes things are UTF-8. How do I do convert this, or cause the string to be created with the right encoding?
I tried setting the string on the USB device to be UTF-8 encoded, and it’s not returning the right string in that case, either. I'm not sure where the disconnect lies.
I don't know what the right string is you mentioned. If you have a String that's not stored using using UTF-8 encoding, you can use makeContiguousUTF8 or withUTF8.
What is failing here? More importantly, what is returned by the IOHIDDeviceGetProperty? CFString can normally convert to String, even dynamically:
let x: CFTypeRef = "Test" as CFString
if let x = x as? String {
print(x) // Test
}
And it's likely not about encoding. String supports other bridged formats by default (at a cost of lower speed). Otherwise, we wouldn't have makeContiguousUTF8.
Here's the background, sorry it's getting pretty off-topic for Swift; I had initially just tried to see if something was failing in the Swift-C bridge. I'm building a little USB HID device, and using IOHIDManager to talk to it. The firmware for the device is written in C/C++, using GCC for ARM, and a library called TinyUSB. USB is officially USB-16LE, but it seems that's not well-enforced by anyone.
And just now it dawns on me that the TinyUSB library is not letting me set the Product String sequence to a UTF-16-encoded string, because it's setting the first \0 and stopping. So I have to get past that first.
Okay it seems the TinyUSB API (the way it’s used in Arduino) takes UTF-8 strings and converts them internally to UTF-16 encoding. So my string u8"Wahangū" shows up in USB Prober as "Wahang\u016b", and gets read by IOHIDDeviceGetProperty() and converted to String:
if let ps = IOHIDDeviceGetProperty(self.device, "Product" as CFString) as? String
{
debugLog("Product: \(ps)")
}