Search code examples
swiftcfdictionary

CFDictionary get Value for Key in Swift3


I've a problem with accessing a specific (or any) key in a CFDictionary. Honestly I don't really get the way you need to do this in Swift and I think it's overly complicated...

My Code:

if let session = DASessionCreate(kCFAllocatorDefault) {
let mountedVolumes = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: [], options: [])!
for volume in mountedVolumes {
    if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volume as CFURL) {
        let diskinfo = DADiskCopyDescription(disk);   

        var volumeValue = CFDictionaryGetValue(diskinfo, <#T##key: UnsafeRawPointer!##UnsafeRawPointer!#>)


    }
}

What I want to achieve: Get the Value for the Key or field DAVolumeNetwork into the variable volumeValue. I guess I need to pass the kDADiskDescriptionVolumeNetworkKey to the CFDictionaryGetValue Method? How do I achieve this?


Solution

  • Don't use CFDictionary in Swift. (It is possible, but not worth the effort, see below.)

    • CFDictionary is toll-free bridged with NSDictionary, which in turn can be cast to a Swift Dictionary.
    • The value of the kDADiskDescriptionVolumeNetworkKey key is a CFBoolean which can be cast to a Swift Bool.

    Example:

    if let session = DASessionCreate(kCFAllocatorDefault),
        let mountedVolumes = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: []) {
        for volume in mountedVolumes {
            if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volume as CFURL),
                let diskinfo = DADiskCopyDescription(disk) as? [NSString: Any] {
    
                if let networkValue = diskinfo[kDADiskDescriptionVolumeNetworkKey] as? Bool {
                    print(networkValue)
                }
            }
        }
    }
    

    Just for the sake of completeness: This is the necessary pointer juggling to call CFDictionaryGetValue in Swift 3:

    if let session = DASessionCreate(kCFAllocatorDefault),
        let mountedVolumes = FileManager.default.mountedVolumeURLs(includingResourceValuesForKeys: []) {
        for volume in mountedVolumes {
            if let disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, volume as CFURL),
                let diskinfo = DADiskCopyDescription(disk) {
    
                if let ptr = CFDictionaryGetValue(diskinfo, Unmanaged.passUnretained(kDADiskDescriptionVolumeNetworkKey).toOpaque()) {
                    let networkValue = Unmanaged<NSNumber>.fromOpaque(ptr).takeUnretainedValue()
                    print(networkValue.boolValue)
                }
            }
        }
    }