Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
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
or withUnsafeMutablePointer(to:)
.
Instead, you can just use
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
if status == noErr, let data = result as? Data {
//use data...
Generally, when you need to pass an UnsafeMutablePointer<T>
to a function, declare a variable of type T
and pass it as an inout argument &variable
. In your case, T
is CFTypeRef?
, and in Swift 3, CFTypeRef
is just a typealias of AnyObject
.
Even in Swift 2.2, you did not need to use withUnsafeMutablePointer
var result: AnyObject?
let status = SecItemCopyMatching(query, &result)
–
The error message is somewhat misleading - the actual problem is that result
has to be an AnyObject?
- withMemoryRebound
doesn't need to be used.
var result: AnyObject?
let status = withUnsafeMutablePointer(to: &result){
SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0))
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
var query: [String : AnyObject] = [:]
//set up the query
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
var data: Data?
if status == noErr{
data = result as? Data
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.