7
votes

We had this snippet of code with the previous version of Swift

    var retrievedData: NSData?
    var extractedData: Unmanaged<AnyObject>? = nil
    let status = SecItemCopyMatching(keyChainQuery, &extractedData)

    if (status == errSecSuccess) {
        if let validExtractedData = extractedData {
            let opaque = validExtractedData.toOpaque()
            retrievedData = Unmanaged<NSData>.fromOpaque(opaque).takeUnretainedValue()
        }
    }

However this now gives us the following error:

Cannot convert value of type 'inout Unmanaged?' (aka 'inout Optional>') to expected argument type 'UnsafeMutablePointer' (aka 'UnsafeMutablePointer>')

I'm a bit lost on how to fix it. I presume I have to allocate some memory, make an UnsafeMutablePointer to it and then supply this to SecItemCopyMatching?

I tried this:

    let sizeOfKey = 32
    var store = NSMutableData(capacity: sizeOfKey)!
    let status = SecItemCopyMatching(keyChainQuery, store.bytes)

But this gave me an:

Cannot convert value of type 'UnsafePointer' (aka 'UnsafePointer<()>') to expected argument type 'UnsafeMutablePointer' (aka 'UnsafeMutablePointer>') error

Anyone an idea?

2

2 Answers

26
votes

It seems, we don't need Unmanaged<> work anymore.

Try:

var retrievedData: NSData?
var extractedData: AnyObject?
let status = SecItemCopyMatching(keyChainQuery, &extractedData)

if (status == errSecSuccess) {
    retrievedData = extractedData as? NSData
}
0
votes

After puzzling some more I've come up with this solution:

    var retrievedData: NSData?
    let sizeOfKey = 32
    let store = UnsafeMutablePointer<AnyObject?>.alloc(sizeof(AnyObject?) * sizeOfKey)
    let status = SecItemCopyMatching(keyChainQuery, store)

    if (status == errSecSuccess) {
        retrievedData = NSData(bytesNoCopy: store, length: sizeOfKey, freeWhenDone: true)
    }

Which compiles. I'm not sure if it actually works yet. If it does I'll update this post. In the meantime if people in the know can comment on it that would be great!