Reputation: 30
I have a Core Foundation dictionary that I would like to find a specific value in. Naturally I would use CFDictionaryContainsValue() provided by Core Foundation. The first argument is the Core Foundation dictionary to search and the second argument is of type UnsafePointer<Void>
. I'm looking for a string in the dictionary so I tried something like this:
var deviceToFind = "disk1"
var result: kern_return_t = KERN_FAILURE
let classesToMatch = IOServiceMatching(kIOMediaClass)
let classesToMatchDict = (classesToMatch as NSDictionary) as! Dictionary<String, AnyObject>
let matchedDevices = (classesToMatchDict as NSDictionary) as CFDictionaryRef
result = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatchCFDictRef, &storageIterator);
if CFDictionaryContainsValue(matchedDevices, &deviceToFind) == true
{
print("Found disk1")
}
But that just crashes (EXC_BAD_ACCESS) at the call to CFDictionaryContainsValue()
. According to Apple's documentation for interacting with UnsafePointers I'm structuring the call correctly but there's obviously a problem but I'm unsure of how to get it to work.
Upvotes: 1
Views: 278
Reputation: 285064
To get the BSD name from IOReg you cannot retrieve the value from matchedDevices
directly. You have to iterate through the storageIterator
and get the BSD name property respectively.
var deviceToFind = "disk1"
var storageIterator = io_iterator_t()
var object : io_object_t
var result: kern_return_t = KERN_FAILURE
let classesToMatchDict = IOServiceMatching("IOMedia")
result = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatchDict, &storageIterator)
if KERN_SUCCESS == result && storageIterator != 0 {
repeat {
object = IOIteratorNext(storageIterator)
if let data = IORegistryEntryCreateCFProperty(object, kIOBSDNameKey, kCFAllocatorDefault, 0), disk = data.takeRetainedValue() as? String {
if deviceToFind == disk {
print("Found \(deviceToFind)")
break
}
}
} while object != 0
IOObjectRelease(storageIterator)
}
Upvotes: 1
Reputation: 7084
It might be less friction to coerce the CFDictionary to a Swift dictionary and then use Swift primitives.
If you need to stay in CF-land, the following should work:
let value = "VALUE" as NSString
let dict = ["KEY": "VALUE"] as CFDictionary
if CFDictionaryContainsValue(dict, unsafeAddressOf(value)) {
print("contains value")
} else {
print("does not contain value")
}
Upvotes: 0