tutorial receive notification how ios objective-c ios8 apple-push-notifications keychain

receive - push notifications ios swift 4



Acción de notificación de iOS 8: error "Acceso al elemento intentado mientras el llavero está bloqueado" al acceder al llavero en "didFinishLaunchingWithOptions" (2)

El acceso al llavero está bloqueado cuando tiene una contraseña en su dispositivo y el dispositivo está bloqueado. Por lo tanto, no puede realizar ninguna acción con el llavero desde la pantalla de bloqueo si tiene una contraseña.

Estoy observando un error de llavero en la consola del dispositivo lanzada por SecItemCopyMatching al actuar sobre una notificación de inserción de iOS 8 en un teléfono bloqueado. Los pasos detallados de repro son los siguientes:

  1. Desinstala todas las versiones anteriores de la aplicación. Construye una versión de AppStore de la aplicación en el dispositivo. Forzar la salida de la aplicación.
  2. Incremente el número de compilación y genere una versión más nueva en el dispositivo. Esto simula un flujo de actualización de la aplicación. Forzar la salida de la aplicación (en la vida real, la aplicación podría ser asesinada por el sistema operativo debido a la presión de la memoria. La acción de abandonar la fuerza simula este comportamiento)
  3. Envíe una notificación de inserción a la aplicación cuando el teléfono esté bloqueado.
  4. Con el teléfono bloqueado, deslícese hacia la izquierda para ver los botones de acción y presione uno de los botones de acción.
  5. La aplicación se didFinishLaunchingWithOptions , se llama didFinishLaunchingWithOptions , que intenta acceder a un elemento de llavero. Mientras se ejecuta SecItemCopyMatching , SecItemCopyMatching un error en el Access to item attempted while keychain is locked en la consola del dispositivo.

El registro de errores completo se muestra a continuación. La última línea muestra el mensaje de error específico de la aplicación.

ReportCrash[32481] <Error>: task_set_exception_ports(B07, 400, D03, 0, 0) failed with error (4: (os/kern) invalid argument) ReportCrash[32481] <Notice>: ReportCrash acting against PID 31423 diagnosticd[32258] <Error>: error evaluating process info - pid: 31423, punique: 131317 ReportCrash[32481] <Notice>: Formulating crash report for process cfprefsd[31423] com.apple.xpc.launchd[1] (com.apple.cfprefsd.xpc.daemon[31423]) <Notice>: Service exited due to signal: Bus error: 10 My App[32480] <Error>: assertion failed: 12F70: libxpc.dylib + 71768 [B870B51D-AA85-3686-A7D9-ACD48C5FE153]: 0x7d Unknown[32480] <Error>: ReportCrash[32481] <Notice>: Saved report to /Library/Logs/CrashReporter/cfprefsd_2015-07-02-150139_Xianjing-Hus-iPhone.ips securityd[32279] <Error>: s3dl_query_row decode genp,rowid=8099 failed (-25308): The operation couldn’t be completed. (OSStatus error -25308 - ks_crypt: e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.) securityd[32279] <Error>: securityd_xpc_dictionary_handler Okta Verify[32480] copy_matching The operation couldn’t be completed. (OSStatus error -25308 - ks_crypt: e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.) My App[32480] <Error>: SecOSStatusWith error:[-25308] The operation couldn’t be completed. (OSStatus error -25308 - Remote error : The operation couldn''t be completed. (OSStatus error -25308 - ks_crypt: e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.))

Unas pocas cosas:

  • La accesibilidad del elemento de llavero se establece en kSecAttrAccessibleAlways .
  • Como se puede ver en el registro del dispositivo anterior, siempre hay una cfprefsd proceso de cfprefsd antes del problema.
  • Este problema solo ocurre en las versiones de Appstore, no en las versiones de depuración.
  • Este problema solo se produce cuando se intenta actuar sobre una notificación en un teléfono bloqueado.
  • Este problema solo ocurre cuando la aplicación se actualiza recientemente, como se describe en los pasos de reproducción anteriores.
  • Debido a que fuerzo la salida de la aplicación, cuando llega la notificación de inserción y presiono el botón de acción, mi aplicación se iniciará en segundo plano. didFinishLaunchingWithOptions se llama, y ​​dentro de este método de delegado, estoy haciendo el acceso a mi llavero que produce el error.

¿Alguien ha visto un error similar y, de ser así, cómo resolvió el problema? Cualquier ayuda es apreciada.

Actualización: cfprefsd registro de cfprefsd

Exception Type: EXC_BAD_ACCESS (SIGBUS) Exception Subtype: unknown at 0x00000001007d4000 Triggered by Thread: 2 Thread 0 name: Dispatch queue: com.apple.libdispatch-manager Thread 0: 0 libsystem_kernel.dylib 0x0000000197d88c24 kevent64 + 8 1 libdispatch.dylib 0x0000000197c6de6c _dispatch_mgr_invoke + 272 2 libdispatch.dylib 0x0000000197c5f998 _dispatch_mgr_thread + 48 Thread 1 name: Dispatch queue: com.apple.root.default-qos.overcommit Thread 1: 0 libsystem_kernel.dylib 0x0000000197da3984 __sigsuspend_nocancel + 8 1 libdispatch.dylib 0x0000000197c6921c _dispatch_sigsuspend + 24 2 libdispatch.dylib 0x0000000197c69200 _dispatch_sig_thread + 44 Thread 2 name: Dispatch queue: src Thread 2 Crashed: 0 libsystem_platform.dylib 0x0000000197e35300 _platform_memmove + 176 1 libxpc.dylib 0x0000000197e6567c xpc_data_create + 84 2 CoreFoundation 0x0000000185d5a9b8 -[CFPDSource acceptMessage:] + 1956 3 CoreFoundation 0x0000000185dc0da8 __handle_synchronize_message_block_invoke103 + 172 4 CoreFoundation 0x0000000185d57c58 __88+[CFPDSource withSourceForDomain:inContainer:user:byHost:managed:synchronously:perform:]_block_invoke_2 + 24 5 CoreFoundation 0x0000000185d5955c __25-[CFPDSource lockedSync:]_block_invoke + 44 6 libdispatch.dylib 0x0000000197c5d950 _dispatch_client_callout + 12 7 libdispatch.dylib 0x0000000197c671e0 _dispatch_barrier_sync_f_invoke + 72 8 CoreFoundation 0x0000000185d59520 -[CFPDSource lockedSync:] + 80 9 CoreFoundation 0x0000000185d57c0c __88+[CFPDSource withSourceForDomain:inContainer:user:byHost:managed:synchronously:perform:]_block_invoke + 504 10 libdispatch.dylib 0x0000000197c5d950 _dispatch_client_callout + 12 11 libdispatch.dylib 0x0000000197c671e0 _dispatch_barrier_sync_f_invoke + 72 12 CoreFoundation 0x0000000185d576fc +[CFPDSource withSourceForDomain:inContainer:user:byHost:managed:synchronously:perform:] + 364 13 CoreFoundation 0x0000000185dc0508 handle_message + 1312 14 CoreFoundation 0x0000000185dc081c __handle_multi_message_block_invoke_2 + 124 15 libxpc.dylib 0x0000000197e657c0 xpc_array_apply + 76 16 CoreFoundation 0x0000000185dc05f8 handle_message + 1552 17 CoreFoundation 0x0000000185dbffd4 ____CFXPreferencesDaemon_main_block_invoke_5 + 132 18 libxpc.dylib 0x0000000197e64cc8 _xpc_connection_call_event_handler + 64 19 libxpc.dylib 0x0000000197e62bcc _xpc_connection_mach_event + 2156 20 libdispatch.dylib 0x0000000197c5da24 _dispatch_client_callout4 + 12 21 libdispatch.dylib 0x0000000197c6113c _dispatch_mach_msg_invoke + 488 22 libdispatch.dylib 0x0000000197c682d0 _dispatch_queue_drain + 2004 23 libdispatch.dylib 0x0000000197c60664 _dispatch_mach_invoke + 132 24 libdispatch.dylib 0x0000000197c6a314 _dispatch_root_queue_drain + 716 25 libdispatch.dylib 0x0000000197c6bc48 _dispatch_worker_thread3 + 104 26 libsystem_pthread.dylib 0x0000000197e3d228 _pthread_wqthread + 812 27 libsystem_pthread.dylib 0x0000000197e3ceec start_wqthread + 0


Este error se debe definitivamente al intentar acceder a un elemento que es kSecAttrAccessibleWhenUnlocked mientras el dispositivo aún está bloqueado. Puede saberlo simplemente mirando la siguiente línea del registro que ha proporcionado:

securityd[32279] <Error>: securityd_xpc_dictionary_handler Okta Verify[32480] copy_matching The operation couldn’t be completed. (OSStatus error -25308 - ks_crypt: e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.)

La clase 6 es kSecAttrAccessibleWhenUnlocked (y kSecAttrAccessibleAlways es la clase 8) - vea la diapositiva 15 de este mazo para obtener más detalles, por lo que se espera el comportamiento que está viendo.

La verdadera pregunta ahora es por qué el elemento termina como kSecAttrAccessibleWhenUnlocked mientras que piensas que es kSecAttrAccessibleAlways . Es difícil decirlo sin ver más código y / o tener más información, pero aquí hay algunas cosas que debe considerar:

  • Los elementos del llavero no se eliminan cuando se desinstala la aplicación, sino que sobreviven a la reinstalación / actualización de la aplicación. Entonces, si una versión anterior de la aplicación creara un elemento como kSecAttrAccessibleWhenUnlocked , podría haber continuado. Intente eliminar el elemento y volver a crearlo (y verifique los valores de retorno de SecItemDelete() y SecItemAdd() para asegurarse de que esté listo).
  • Verifique que kSecAttrAccessibleAlways se pase a SecItemAdd() para que iOS no aplique ningún valor predeterminado por sí solo.
  • Tenga en cuenta que la clase de accesibilidad se debe pasar al crear un elemento (es decir, a SecItemAdd() ) y no al recuperarlo (es decir, no a SecItemCopyMatching() ). Esto es algo obvio, pero nunca está de más repetirlo.

Si ninguna de las anteriores ayuda, por favor, publique un código relevante que muestre cómo se crea el artículo y luego cómo se lee.