2012-01-20 10 views
11

Im desarrollando una aplicación que se debe ejecutar en segundo plano. Es una aplicación basada en la ubicación, por lo que se ejecuta todo el tiempo, el sistema operativo no lo mata.iphone - NSTimers en el fondo

Debe enviar alguna información cada 10 segundos (solo para la depuración), configuré un temporizador una vez que está en segundo plano. Establecí un punto de interrupción en la función que se debe ejecutar cada 10 segundos, que nunca se llama, pero si pause la aplicación y luego continúo se llama al temporizador, y luego el temporizador se ejecuta cada 10 segundos sin problemas, ¿no?

Pensé que el temporizador se estaría ejecutando de todos modos cuando no estaba depurando, pero no es así, lo mismo que si no pause la depuración.

Mi pregunta es ¿POR QUÉ? El temporizador está configurado correctamente (supongo) ya que funciona después de la pausa, pero no es así.

¿Alguna idea?

La forma en que ponía el reloj es:

self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(doStuff) userInfo:nil repeats:YES]; 

Y en la función que se conectan a un servicio web.

Gracias.

+0

Esto se trata de cronómetros, no de depuración; arregla tu título, pls. ¿Y es "objetivo-c" lo mejor que puede hacer para etiquetar esta pregunta? – matt

+0

posible duplicado de [NSTimers ejecutando en segundo plano?] (Http://stackoverflow.com/questions/5901398/nstimers-running-in-background) – matt

Respuesta

20

Tengo un diseño de aplicación similar y estaba atrapado en lo mismo. Lo que encontré algún lugar de Internet es la adición de este tipo de declaración applicationDidEnterBackground:

UIBackgroundTaskIdentifier locationUpdater =[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ 
     [[UIApplication sharedApplication] endBackgroundTask:locationUpdater]; 
     locationUpdater=UIBackgroundTaskInvalid; 
    } ]; 

Esto le indica al sistema operativo que todavía tiene cosas que suceden y no para detenerlo.

tengo mi temporizador adjunta a esta función

//this is a wrapper method to fit the required selector signature 
- (void)timeIntervalEnded:(NSTimer*)timer { 
    [self writeToLog:[NSString stringWithFormat:@"Timer Ended On %@",[NSDate date]]]; 
    [self startReadingLocation]; 
    [timer invalidate]; 
    timer=nil; 
} 

puedo configurar el temporizador en mi ubicación mis métodos gestor de delegado.

Siento tu dolor. Descubrí que estas cosas eran súper meticulosas. Esto es lo que funcionó para mí. Espero que ayude. He descubierto que no hay realmente restricciones en lo que puedes hacer en segundo plano.

+0

muchas gracias cwieland, funcionó perfectamente. – subharb

+0

En realidad, no solucionó todo mi problema. Ahora obtengo un registro de bloqueo, al parecer porque no finalizo la tarea en segundo plano, y eso se debe a que la tarea nunca debe terminar mientras la aplicación esté en segundo plano. El NStimer se repetirá definitivamente. ¿Es eso posible? o como es una aplicación de ubicación, ¿debo enganchar las acciones al GPS? – subharb

+0

No estoy exactamente seguro de qué es el bloqueo. Puedo mantener una conexión de socket en segundo plano, así que estoy bastante seguro de que no estás restringido solo a las cosas basadas en la ubicación. Pero como dije, estos problemas no son los más fáciles de resolver. Lo siento, no podría ser de más ayuda. Mi temporizador se ejecutará sin fin (por lo que he visto) una cosa para comprobar es imprimir el backgroundTimeRemaining (nunca debería bajar y ser muy grande) – utahwithak

0

Puede haber restricciones sobre lo que puede hacer en segundo plano. Intente agregar el temporizador al ciclo de ejecución antes de pasar al fondo. Incluso eso podría no funcionar; Es posible que el único código que pueda ejecutarse en segundo plano sea el código invocado por los métodos de Ubicación principal para los que se haya registrado (por ejemplo, locationManager:didUpdate...). Pero mi impresión es que los temporizadores que ya se están ejecutando antes de comenzar a pasar al segundo plano continuarán ejecutándose.

+0

Pero eso no explica por qué si depuro funciona. Eso es lo que no entiendo. Supongo que la aplicación se comporta de la misma manera que la depuración o simplemente ejecutando – subharb

+0

Creo que si hubiera intentado lo que sugerí (configurar el temporizador mientras aún estaba en primer plano) habría resuelto el problema. De hecho, esto es probablemente lo mismo que la solución que usted aceptó. Tu problema fue que ya estabas atrasado y tu runloop había dejado de funcionar antes de configurar el temporizador. Pausar en un punto de interrupción y reanudar mientras está en segundo plano le da a su runloop una nueva oportunidad de ejecución, por lo que en ese punto el temporizador se agregó al runloop. Eso es conjetura pero creo que explica los fenómenos. – matt

Cuestiones relacionadas