¿Por qué una lectura falla con un error de etiqueta perdida?
Porque la etiqueta salió del campo antes de que terminara el intercambio, cosa que una mano hace en medio segundo. Android lanza TagLostException desde cualquier operación que toque la radio, iOS falla con un error de conexión perdida, y una escritura cortada así deja un resultado que todavía no conoce nadie.
Lo que lanza cada plataforma
En Android puede lanzarla cualquier operación que toque la radio. La referencia de TagLostException la hace subclase de IOException, y connect(), transceive(), readPages() y writePage() la declaran todas. Un error distinto significa un problema distinto: reutilizar un objeto Tag después de que su etiqueta se haya ido lanza SecurityException, ya que ese objeto pertenecía a una sola aparición.
En iOS el mismo suceso llega como un código de error. readerTransceiveErrorTagConnectionLost dice que el lector ha perdido la conexión con la etiqueta, y sus vecinos nombran los demás casos: readerTransceiveErrorTagNotConnected cuando la etiqueta no está en estado conectado, readerTransceiveErrorSessionInvalidated cuando la sesión ha terminado por debajo, y readerTransceiveErrorRetryExceeded cuando ha habido demasiados reintentos.
La mano primero, el código después
Las causas físicas van primero porque son las frecuentes. Una escritura tarda más que una lectura, así que un gesto que lee con fiabilidad puede ser demasiado breve para escribir, cosa que la página de la escritura a medias describe desde el lado de quien usa el teléfono. Una funda gruesa, una etiqueta pequeña o un ángulo incómodo no dejan margen, y la etiqueta sale de alcance con un milímetro de movimiento.
Las causas de código son más sutiles. Cada comando es una ida y vuelta, así que una secuencia de veinte deja veinte ocasiones de perder la etiqueta, y el trabajo hecho entre dos comandos, un cálculo o peor una llamada de red, mantiene la etiqueta abierta sin motivo. Abrir otra clase de tecnología a mitad de secuencia puede hacer que la plataforma reseleccione la etiqueta, cosa que la página de la autenticación cubre allí donde más cuesta.
Qué hacer con la etiqueta que has perdido
Trata una etiqueta perdida durante una escritura como un resultado desconocido y no como un fallo. El comando puede haber llegado a la etiqueta antes de que se perdiera la respuesta, así que el paso siguiente es volver a leer la memoria y no volver a escribir, y un orden que no deje nada a medio validar lo hace legible: la página de las escrituras cortadas lo expone.
Y luego empieza por el principio. La etiqueta que vuelve es una detección nueva, un objeto Tag nuevo en Android y una detección nueva en iOS, cualquier autenticación se ha ido, y una secuencia no se puede retomar por la mitad. El código que conserva estado a través de una pérdida tiene que conciliarlo con lo que lee de vuelta.
Hacer la ventana lo bastante ancha
Acorta el intercambio en vez de alargar la espera. Lee en los bloques más grandes que ofrezca el protocolo, baja el número de comandos, y haz antes del toque todo lo que no necesite la etiqueta, la aritmética que la página de los tiempos de espera hace explícita.
Y luego diseña la interfaz para una mano. Dile a quien usa el teléfono cuándo apartarlo, enseña que ha terminado solo cuando la llamada ha vuelto, y prueba con el teléfono en la mano y no plano sobre una mesa, donde la ventana no se cierra nunca y el fallo no aparece.
Preguntas frecuentes
¿Un error de etiqueta perdida significa que la etiqueta está rota?
Casi nunca. Significa que la etiqueta salió del campo a mitad de intercambio. Esa misma etiqueta suele leerse al intento siguiente si el teléfono se sostiene quieto.
¿Puedo retomar un intercambio cuando la etiqueta vuelve?
No. La etiqueta que vuelve es una detección nueva, y cualquier autenticación se ha ido. Empieza por la detección, y lee de vuelta antes de volver a escribir.
¿Por qué falla una escritura más a menudo que una lectura?
Tarda más, así que necesita sostener el teléfono más tiempo. Un gesto que lee con fiabilidad es a menudo demasiado breve para escribir.
¿Qué pinta aquí SecurityException?
Significa que el código ha reutilizado un objeto Tag de una aparición anterior. Cada detección da un objeto nuevo, y solo funciona el más reciente.