I'm attempting to call SecItemCopyMatching
in my keychain utility class in order to get data out of the keychain, yet I'm running into a problem with getting the result
argument, UnsafeMutablePointer<CFTypeRef?>
.
The original statement (in Swift 2, before migrating to Swift 3) was
// query is a dictionary of [String : AnyObject]
var result: Data?
let status = withUnsafeMutablePointer(to: &result) {
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
}
But in Swift 3, you are now required to call .withMemoryRebound
in order to view memory. Based on what Xcode tells you to do, I tried this
var result: Data?
let status = withUnsafeMutablePointer(to: &result){
$0.withMemoryRebound(to: Data.self, capacity: 1){
SecItemCopyMatching(query as CFDictionary, UnsafePointer($0))
}
}
Yet doing this, I get an error
Cannot convert value of type '
UnsafePointer<_>
' to expected argument type 'UnsafeMutablePointer<CFTypeRef?>?
'
So, I tried using CFTypeRef
instead of Data
var result: CFTypeRef?
let status = withUnsafeMutablePointer(to: &result){
$0.withMemoryRebound(to: CFTypeRef.self, capacity: 1){
SecItemCopyMatching(query as CFDictionary, UnsafePointer($0))
}
}
Replacing UnsafePointer($0)
with simply $0
results in the same error message.
How can I get an UnsafeMutablePointer<CFTypeRef?>
for getting data from keychain?
In your case, you do not need to use
withMemoryRebound
orwithUnsafeMutablePointer(to:)
.Instead, you can just use
Generally, when you need to pass an
UnsafeMutablePointer<T>
to a function, declare a variable of typeT
and pass it as an inout argument&variable
. In your case,T
isCFTypeRef?
, and in Swift 3,CFTypeRef
is just a typealias ofAnyObject
.Even in Swift 2.2, you did not need to use
withUnsafeMutablePointer
The error message is somewhat misleading - the actual problem is that
result
has to be anAnyObject?
-withMemoryRebound
doesn't need to be used.Works as expected and gets the correct result from keychain - it just needs to be casted to
Data
. In fact,withUnsafeMutablePointer
doesn't even have to be used.So, my new code is