swift swift3 core-foundation unsafe-pointers unsafemutablepointer

UnsafeMutablePointer<CFTypeRef> en Swift 3



swift3 core-foundation (2)

Estoy intentando llamar a SecItemCopyMatching en mi clase de utilidad de llavero para obtener datos del llavero, pero estoy teniendo un problema al obtener el argumento de result , UnsafeMutablePointer<CFTypeRef?> .

La declaración original (en Swift 2, antes de migrar a Swift 3) era

// query is a dictionary of [String : AnyObject] var result: Data? let status = withUnsafeMutablePointer(to: &result) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }

Pero en Swift 3, ahora se requiere que llame a .withMemoryRebound para ver la memoria. Según lo que Xcode te dice que hagas, probé esto

var result: Data? let status = withUnsafeMutablePointer(to: &result){ $0.withMemoryRebound(to: Data.self, capacity: 1){ SecItemCopyMatching(query as CFDictionary, UnsafePointer($0)) } }

Sin embargo, al hacer esto, me sale un error

No se puede convertir el valor del tipo '' UnsafePointer<_> '' al tipo de argumento esperado '' UnsafeMutablePointer<CFTypeRef?>? ''

Entonces, traté de usar CFTypeRef lugar de Data

var result: CFTypeRef? let status = withUnsafeMutablePointer(to: &result){ $0.withMemoryRebound(to: CFTypeRef.self, capacity: 1){ SecItemCopyMatching(query as CFDictionary, UnsafePointer($0)) } }

Reemplazar UnsafePointer($0) con simplemente $0 resulta en el mismo mensaje de error.

¿Cómo puedo obtener un UnsafeMutablePointer<CFTypeRef?> Para obtener datos de keychain?


En su caso, no necesita usar withMemoryRebound o withUnsafeMutablePointer(to:) .

En cambio, puedes usar

var result: AnyObject? let status = SecItemCopyMatching(query as CFDictionary, &result) if status == noErr, let data = result as? Data { //use data... }

Generalmente, cuando necesita pasar un UnsafeMutablePointer<T> a una función, declare una variable de tipo T y páselo como un argumento &variable inout. En su caso, T es CFTypeRef? , y en Swift 3, CFTypeRef es solo una tipografía de AnyObject .

Incluso en Swift 2.2, no era necesario usar withUnsafeMutablePointer

var result: AnyObject? let status = SecItemCopyMatching(query, &result)


El mensaje de error es algo engañoso: ¿el problema real es que el result tiene que ser un AnyObject? - withMemoryRebound no necesita ser utilizado.

var result: AnyObject? let status = withUnsafeMutablePointer(to: &result){ SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }

Funciona de la manera esperada y obtiene el resultado correcto del llavero: solo debe transferirse a Data . De hecho, withUnsafeMutablePointer ni siquiera tiene que ser utilizado .

Entonces, mi nuevo código es

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 }