Código de error OSStatus -34018

Estoy usando SecItemCopyMatching para acceder al llavero iOS. Aproximadamente 1 de cada 100 veces obtengo un código de resultado -34018 justo después de relanzar la aplicación desde el background. La documentation dice:

El espacio de error asignado para los services de Keychain es discontinuo: -25240 a -25279 y -25290 a -25329. Los Servicios de artículos de llavero también pueden devolver los códigos de resultado no ERR (0) o paramErr (-50), o CSSM

Parece que -34018 es un "código de resultado CSSM". He seguido el enlace sugerido pero no pude encontrar los códigos de resultado.

¿Qué es el código de resultado -34018 ? ¿Cómo puedo get un acceso de llavero más confiable?

 - (NSData *)getKeychainData:(NSString *)key { NSDictionary *query = @{ (__bridge id)kSecClass:(__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService:SEC_ATTR_SERVICE, (__bridge id)kSecAttrAccount:key, (__bridge id)kSecReturnData:@YES }; CFDataRef result = nil; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); if(status == errSecItemNotFound) { return nil; } if(status == noErr) { return CFBridgingRelease(result); } else { [self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil]; return nil; } } 

He estado investigando el mismo error.

Lo esencial es que el service de security que usa Apple para comunicarse con el llavero, en casos raros, cuando el dispositivo del usuario tiene poca memory, se cuelga y le quita la capacidad de la aplicación para hablar con el llavero, lo que resulta ser la peor, 34018

Esto no está sucediendo solo mientras se ejecuta a través de Xcode como algunos pueden reclamar.

Estos son los datos más recientes sobre el tema tomado de los foros de desarrolladores de Apple por parte de uno de los empleados de Apple:

ACTUALIZACIÓN: finalmente hemos podido reproducir el error -34018 en iOS 8.3. Este es el primer paso para identificar la causa raíz y, luego, encontrar una solución.

Como es habitual, no podemos comprometernos con un marco de time de lanzamiento, pero esto ha afectado a muchos desarrolladores y realmente queremos resolverlo.

Anteriormente sugerí agregar un pequeño retraso en la aplicación: didFinishLaunchingWithOptions y applicationDidBecomeActive: antes de acceder al llavero como solución. Sin embargo, eso en realidad no parece ayudar. Eso significa que no hay ninguna solución conocida en este momento que no sea el relanzamiento de la aplicación.

El problema parece estar relacionado con la presión de la memory, por lo que tal vez ser más agresivo al manejar advertencias de memory puede aliviar el problema.

De otro miembro del personal de Apple:

  • La ingeniería de Keychain es muy consciente de lo importante que es este problema.
  • El problema principal ha sido reproducir la falla aquí en Apple.
  • Ahora podemos hacerlo (en gran parte gracias al trabajo que ustedes han puesto en la presentación y seguimiento de sus informes de errores).

De otro miembro del personal de Apple el 22 de marzo de 2016 :

OK, aquí está lo último. Este es un problema complejo con múltiples causas posibles: Algunas instancias del problema son causadas por la firma incorrecta de la aplicación. Puede distinguir fácilmente este caso porque el problema es 100% reproducible. Algunas instancias del problema son causadas por un error en la forma en que iOS admite el desarrollo de aplicaciones (r 23,991,853). La debugging fue complicada por el hecho de que otro error en el sistema operativo (r. 23.770.418) enmascaraba su efecto, lo que significa que el problema solo surgió cuando el dispositivo estaba bajo presión de memory. Creemos que estos problemas se resolvieron en iOS 9.3. Sospechamos que puede haber más causas de este problema. Por lo tanto, si ve este problema en un dispositivo de usuario (uno que Xcode no ha hablado) que ejecuta iOS 9.3 o posterior, presente un informe de error al respecto. Intente include el logging del sistema del dispositivo en su informe de errores (me doy count de que puede ser complicado cuando se trata de dispositivos de clientes; una opción es pedirle al cliente que instale Apple Configurator, lo que les permite ver el logging del sistema). Y si presenta un error, publique su número de error, solo para que conste. En nombre de Apple, me gustaría agradecerles a todos por sus esfuerzos para ayudar a rastrear este tema bastante horrible. Comparte y Disfruta

Lamentablemente, no existen soluciones conocidas y el problema todavía no se soluciona en 9.3.2 Beta 1 (13F51a)

Después de un poco de investigación, encontré esto: http://opensource.apple.com/source/Security/Security-55471/sec/Security/SecBasePriv.h

Entonces, -34018 es errSecMissingEntitlement y el comentario dice

 Internal error when a requinetworking entitlement isn't present. 

¿Experimenta este error mientras ejecuta sus testings de unidad? Si es así, esto podría ayudar: https://stackoverflow.com/a/22305193/171933

Este problema en github dice que solo parece suceder mientras se depura desde Xcode: https://github.com/soffes/sskeychain/issues/97 (también ver https://stackoverflow.com/a/28256591/171933 )

¡Con suerte algo de esto te ayudará!

Este código funciona para mí:

 static const UInt8 kKeychainItemIdentifier[] = "com.apple.dts.KeychainUI\0"; - (NSData *)getKeychainData:(NSString *)key { NSData *keychainItemID = [NSData dataWithBytes:kKeychainItemIdentifier length:strlen((const char *)kKeychainItemIdentifier)]; NSDictionary *query = @{ (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword, (__bridge id)kSecAttrService: SEC_ATTR_SERVICE, (__bridge id)kSecAttrAccount: key, (__bridge id)kSecReturnData: (__bridge id)kCFBooleanTrue, (__bridge id)kSecAttrGeneric: keychainItemID }; CFDataRef result = NULL; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); if(status == errSecItemNotFound) { return nil; } if(status == noErr) { return CFBridgingRelease(result); } else { [self logError:[NSString stringWithFormat:@"SecItemCopyMatching status %d", (int)status] :nil]; return nil; } } 

La principal diferencia con el código de OP es la adición de un atributo genérico a la consulta. El identificador de artículo de llavero es el valor pnetworkingeterminado de apple. La razón detrás de esto viene a diferenciar posibles elementos de llavero diferentes entre sí. Esta es una forma de hacer más un acceso más confiable a los artículos de llavero. Básicamente, en otras palabras, esto asegura que accedes al llavero pnetworkingeterminado de Apple.

Después de probar muchas de las correcciones en el desbordamiento de stack, las cosas aún no funcionaron para mí.

Lo que funcionó fue cambiar la capacidad de compartir llaveros en Xcode. Construido y ejecutado y funcionó de inmediato.

introduzca la descripción de la imagen aquí