Reloj interno en el modo de background de iPhone

En mi aplicación, quiero ejecutar un reloj interno en modo de background [mientras la aplicación no se ejecuta en primer plano].

Toda la funcionalidad será así:

El objective es lograr que el server use en la aplicación, ya que el uso del time del dispositivo a veces puede causar problemas. Los problemas pueden estar en situaciones como que alguien ha cambiado el time del iPhone del usuario, etc. Así que estoy siguiendo el siguiente método.

-Expedición de un reloj interno en el background de mi aplicación, incluso si la aplicación no se está ejecutando. -Communicate con el server cada 15 minutos para get el time real y ejecutar un timer. -Si la networking está desconectada en el medio, el timer continuará y tomará el time del timer.

Mi aplicación depende en gran medida de este factor de time, ya que se trata de un sistema de reserva de tickets. ¿Ayudarme ayudando a implementar esto o confirmar si esto es posible o no?

Estoy desarrollando una aplicación de iPhone que implica el sistema de reserva de billetes. Registré mi aplicación como location basada porque utiliza la location del usuario tomada en segundo plano para un propósito.

Mi problema es que necesito ejecutar un reloj interno en mi aplicación en modo de background. Necesito escribir los códigos para el reloj interno en los methods de delegación de location central, de modo que el reloj interno también se ejecutará junto con los services de location bsed. ¿Se rechazará mi aplicación? ¿Hay algo de malo en hacerlo así?

Necesito get la hora correcta para usar en mi aplicación, por lo que estoy ejecutando este reloj interno. Puedo usar NSDate, pero eso devolverá la hora del dispositivo. Cualquiera puede cambiar la hora del dispositivo. De modo que, una vez que alguien lo haya engañado, el time incorrecto afectará el buen funcionamiento de la aplicación. Por favor, ¿algún cuerpo sugiere que tengas la hora correcta sin correr el reloj interno?

Actualización: siento decir que mi respuesta original no es correcta. Cuando el dispositivo se va a dormir (puede suceder en algún momento después de haberlo bloqueado), el reloj interno de la CPU deja de marcar, y mach_absolute_time tampoco se actualizará. Teóricamente devolverá el mismo valor exacto si lo llama justo antes de que el dispositivo se fuera a dormir, y después de que se despierte.

La mejor manera disponible que conozco para verificar los cambios de date es kern.boottime , mantiene el time de arranque y se modifica cada vez que cambia la hora del sistema. Entre otras cosas, kern.boottime se actualizará si el usuario cambia la hora, o si el sistema operativo cambia la hora de acuerdo con la información de las torres de celulares.

Entonces, en su caso, puede tomar la hora original que calculó y modificar de acuerdo con las modificaciones en kern.boottime. Si ve que kern.boottime cambió significativamente, puede significar que el dispositivo se apagó y, en este caso, tendrá que ponerse en contacto con el server para pedirle el time hasta el vuelo.

Código relevante:

 time_t getBootTimeSecs(void) { struct timeval boottime; size_t size = sizeof(boottime); int ret = sysctlbyname("kern.boottime", &boottime, &size, NULL, 0); assert(ret == 0); return boottime.tv_sec; } 

Respuesta original (incorrecta): Puede usar mach_absolute_time que no se ve afectado por los cambios de date realizados por el usuario.

Cuando reserve el ticket, obtenga la date correcta del server y registre mach_absolute_time . Ahora siempre podrá llamar a mach_absolute_time cuando lo desee, calcule la diferencia de la que registró inicialmente y visualice la date correcta.

Esto solo funcionará mientras el dispositivo no se cerró, en ese caso, tiene sentido que la aplicación vuelva a conectarse al server para get la date correcta.

También puede hacer notifications locales o push para alertar al usuario cuando la date objective se acerque, incluso si la aplicación no se está ejecutando.

apple es una pequeña tarea de soporte para el modo de background que funcionará solo durante aproximadamente 10 segundos.

así que puedes hacer una cosa cuando la aplicación está activa, luego obtén un server de time y actualiza tu hora local según eso.

Creo que solo puedes detectar que la date del dispositivo de iOs se haya modificado (usando NSSystemClockDidChangeNotification). Supongo que usará esta notificación y forzará a recargar la date real de su aplicación desde su server (con un service web).

EDITAR: puede usar el systemUptime en NSProcessInfo:

  NSLog(@"ProcessInfo System uptime: %f",[NSProcessInfo processInfo].systemUptime); 

pero no solucionará su problema si se reinicia el dispositivo.

Creo que hay 2 forms en que puede resolver su problema.

  1. Nunca use el time del sistema. En otras palabras, nunca llame [NSDate date] en su código. Cuando necesite la hora actual, llame a un server NTP. Esto, por supuesto, causará latencia en su aplicación, pero garantizará la precisión.

  2. Cuando la aplicación se inicia o entra en primer plano, verifica que la hora del sistema sea razonablemente precisa frente a un server NTP. Si la hora del sistema está desactivada en más de su nivel de tolerancia, no permita que continúen ejecutando la aplicación hasta que la dirijan. Si la hora del sistema está bien, entonces comience a supervisar para asegurarse de que no cambian la hora del sistema mientras se ejecuta la aplicación (NSSystemClockDidChangeNotification). Si pasan la comprobación inicial, pero al mover el reloj hacia adelante, puede capturar eso y deshabilitar la aplicación hasta que vuelvan a ser exactos.

Aquí hay una implementación de NTP de iOS que podría ser útil para implementar cualquiera de las soluciones anteriores. http://code.google.com/p/ios-ntp/

EDITAR: la aplicación Ticketmaster utiliza la técnica # 2, por lo que parece una solución razonable para una aplicación de tickets que requiere que la hora del sistema sea correcta.

  1. La configuration de zona horaria no debe afectar el time como en UTC
  2. su aplicación no puede ejecutarse en segundo plano. Abusar del requisito de location para esto hará que su aplicación sea rechazada por Apple

así que mi sugerencia: hacer el lado del server lógico con notifications push