I'm developing a program in Swift (for a macOS application) that uses IOKit to retrieve information from a USB device. The app crahes with:
Thread 1: EXC_BAD_ACCESS (code=1,...
on setting CFDictionarySetValue
.
I used the following code:
var matchingDict: CFMutableDictionary?
var val: NSNumber.IntegerLiteralType
var valRef: CFNumber?
matchingDict = IOServiceMatching(kIOHIDDeviceKey)
if let matchingDict {
val = 1917
valRef = CFNumberCreate(kCFAllocatorDefault, CFNumberType.sInt32Type, UnsafeMutableRawPointer?(&val))
CFDictionarySetValue(matchingDict, UnsafeRawPointer?(kIOHIDVendorIDKey), unsafeBitCast(valRef, to: UnsafeRawPointer.self))
I've tried different CFDictionarySetValue
config:
valRef = CFNumberCreate(kCFAllocatorDefault, .sInt32Type, UnsafeMutableRawPointer?(&val))
this rise up a warning (and running it causes a crash):
Forming 'UnsafeRawPointer' to a variable of type 'Optional'; this is likely incorrect because 'Optional' may contain an object reference.
then this one:
CFDictionarySetValue(matchingDict, unsafeBitCast(kIOHIDVendorIDKey, to: UnsafeRawPointer.self), unsafeBitCast(valRef, to: UnsafeRawPointer.self))
Complies Ok but then crashes.
Finally:
CFDictionarySetValue(matchingDict, UnsafeRawPointer?(kIOHIDVendorIDKey), unsafeBitCast(valRef, to: UnsafeRawPointer.self))
but it crashes anyway.
What am I doing wrong?
Instead of updating a CFMutableDictionary
it is much easier to convert it to a Swift Dictionary
. After adding dictionary values, you can convert it back to a CFDictionary
if that is needed for further calls:
if var matchingDict = IOServiceMatching(kIOHIDDeviceKey) as? [String: Any] {
// Add values:
matchingDict[kIOHIDVendorIDKey] = 1917
let cfDict = matchingDict as CFDictionary
// ...
}