ver llavero las guardar guardadas cómo cuentas correo contraseñas contraseña como ios swift keychain

ios - llavero - ver contraseña de correo en iphone



Consulta de llavero iOS usando Swift (3)

Estoy atascado convirtiendo el resultado de la consulta de Keychain usando Swift.

Mi solicitud parece estar funcionando:

let queryAttributes = NSDictionary(objects: [kSecClassGenericPassword, "MyService", "MyAccount", true], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData]) dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { var dataTypeRef : Unmanaged<AnyObject>? let status = SecItemCopyMatching(queryAttributes, &dataTypeRef); let retrievedData : NSData = dataTypeRef!.takeRetainedValue() as NSData *** ^^^^can''t compile this line^^^^ })

Mi problema es que el código no se compilará:

Bitcast requires both operands to be pointer or neither %114 = bitcast %objc_object* %113 to %PSs9AnyObject_, !dbg !487 Bitcast requires both operands to be pointer or neither %115 = bitcast %PSs9AnyObject_ %114 to i8*, !dbg !487 LLVM ERROR: Broken function found, compilation aborted!

No sé cómo convertir Unmanaged<AnyObject> a NSData .

¿Algunas ideas?


Parece que ha pulsado un error del compilador, que debe informar. Puede tomar una ruta diferente para recuperar el valor, como la siguiente:

var dataTypeRef :Unmanaged<AnyObject>? let status = SecItemCopyMatching(queryAttributes, &dataTypeRef); let opaque = dataTypeRef?.toOpaque() if let op = opaque? { let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue() }

El error se manifiesta cuando se utiliza AnyObject como un parámetro de tipo T de Unmanaged<T> . El siguiente fragmento de código se compila sin problemas, que utiliza un tipo más específico, CFError :

let url = NSURL(string:"dummy") var errorRef: Unmanaged<CFError>? let succeeded = CTFontManagerRegisterFontsForURL(url, .Process, &errorRef) if errorRef { let error = errorRef!.takeRetainedValue() }

Como la API de Keychain arroja un resultado diferente según los atributos de la consulta, se requiere el uso de AnyObject .


Para que esto funcione, primero debe acceder al valor retenido de cada constante de llavero. Por ejemplo:

let kSecClassValue = kSecClass.takeRetainedValue() as NSString let kSecAttrAccountValue = kSecAttrAccount.takeRetainedValue() as NSString let kSecValueDataValue = kSecValueData.takeRetainedValue() as NSString let kSecClassGenericPasswordValue = kSecClassGenericPassword.takeRetainedValue() as NSString let kSecAttrServiceValue = kSecAttrService.takeRetainedValue() as NSString let kSecMatchLimitValue = kSecMatchLimit.takeRetainedValue() as NSString let kSecReturnDataValue = kSecReturnData.takeRetainedValue() as NSString let kSecMatchLimitOneValue = kSecMatchLimitOne.takeRetainedValue() as NSString

Luego tendrá que hacer referencia a la constante que creó en el objeto del diccionario de llavero.

var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPasswordValue, service, userAccount, kCFBooleanTrue, kSecMatchLimitOneValue], forKeys: [kSecClassValue, kSecAttrServiceValue, kSecAttrAccountValue, kSecReturnDataValue, kSecMatchLimitValue])

Escribí una publicación en el blog sobre esto en: http://rshelby.com/2014/08/using-swift-to-save-and-query-ios-keychain-in-xcode-beta-4/

¡Espero que esto ayude!

rshelby


Use withUnsafeMutablePointer function y UnsafeMutablePointer struct para recuperar los datos, como los siguientes:

var result: AnyObject? var status = withUnsafeMutablePointer(&result) { SecItemCopyMatching(queryAttributes, UnsafeMutablePointer($0)) } if status == errSecSuccess { if let data = result as NSData? { if let string = NSString(data: data, encoding: NSUTF8StringEncoding) { // ... } } }

funciona bien con la versión de lanzamiento (Fastest [-O]).