How to access CFDictionary in Swift 3?

2019-04-20 08:09发布

问题:

I need to read and write some data from CFDictionary instances (to read and update EXIF data in photos). For the life of me, I cannot figure out how to do this in Swift 3. The signature for the call I want is:

func CFDictionaryGetValue(CFDictionary!, UnsafeRawPointer!)

How the heck do I convert my key (a string) to an UnsafeRawPointer so I can pass it to this call?

回答1:

If you don't have to deal with other Core Foundation functions expecting an CFDictionary, you can simplify it by converting to Swift native Dictionary:

if let dict = cfDict as? [String: AnyObject] {
    print(dict["key"])
}


回答2:

Be careful converting a CFDictionary to a Swift native dictionary. The bridging is actually quite expensive as I just found out in my own code (yay for profiling!), so if it's being called quite a lot (as it was for me) this can become a big issue.

Remember that CFDictionary is toll-free bridged with NSDictionary. So, the fastest thing you can do looks more like this:

let cfDictionary: CFDictionary = <code that returns CFDictionary>
if let someValue = (cfDictionary as NSDictionary)["some key"] as? TargetType {
    // do stuff with someValue
}


回答3:

What about something like:

var key = "myKey"
let value = withUnsafePointer(to: &key){ upKey in
    return CFDictionaryGetValue(myCFDictionary, upKey)
}


回答4:

You can write something like this:

let key = "some key" as NSString
if let rawResult = CFDictionaryGetValue(cfDictionary, Unmanaged.passUnretained(key).toOpaque()) {
    let result = Unmanaged<AnyObject>.fromOpaque(rawResult).takeUnretainedValue()
    print(result)
}

But I guess you would not like to write such thing at any time you retrieve some data from that CFDictionary. You better convert it to Swift Dictionary as suggested in Code Different's answer.