2012-01-20 12 views
11

Sto sviluppando un'applicazione che deve essere eseguita in background. È un'app basata sulla posizione, quindi funziona sempre, il sistema operativo non lo uccide.iphone - NSTimers in background

Dovrebbe inviare alcune informazioni ogni 10 secondi (solo per il debug), ho impostato un timer una volta in background. Ho impostato un punto di interruzione nella funzione che dovrebbe essere eseguita ogni 10 secondi, che non viene mai chiamata, ma se faccio una pausa all'app e poi continuo il timer viene chiamato, e quindi il timer viene eseguito ogni 10 secondi senza problemi, strano vero?

Ho pensato che il timer sarebbe stato eseguito comunque quando non stavo eseguendo il debug, ma non lo è, come se non avessi sospeso il debug.

La mia domanda è PERCHE '?? Il timer è impostato correttamente (presumo) poiché funziona dopo la pausa, ma non lo è.

Qualche idea?

Il modo in cui ho impostato il timer è:

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

E nella funzione mi connetto ad un webservice.

Grazie.

+0

Si tratta di timer, non di debug; correggi il tuo titolo, pls. Ed è "oggettivo-c" il meglio che puoi fare per etichettare questa domanda? – matt

+0

possibile duplicato di [NSTimers in esecuzione in background?] (Http://stackoverflow.com/questions/5901398/nstimers-running-in-background) – matt

risposta

20

Ho un design di app simile ed ero bloccato sulla stessa cosa. Quello che ho trovato da qualche parte su internet è l'aggiunta di questo tipo di istruzione applicationDidEnterBackground:

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

Questo dice al sistema operativo che avete ancora cose in corso e non per fermarlo.

ho il mio timer collegato a questa funzione

//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; 
} 

ho impostato il timer nella mia posizione miei metodi direttore delegato.

Sento il tuo dolore. Ho scoperto che queste cose erano super meticolose. Questo è ciò che ha funzionato per me. Spero possa essere d'aiuto. Ho scoperto che non ci sono davvero restrizioni su ciò che puoi fare in background.

+0

grazie mille, ha funzionato perfettamente. – subharb

+0

In realtà non ha risolto il mio intero problema. Ora ricevo un registro degli arresti anomali, apparentemente perché non concludo l'attività in background, e questo perché l'attività non dovrebbe mai finire finché l'app è in background. NStimer ripeterà endlesly. È possibile? o dato che si tratta di un'app di localizzazione dovrei agganciare le azioni al GPS? – subharb

+0

Non sono esattamente sicuro di quale sia l'arresto. Sono in grado di mantenere una connessione socket in background, quindi sono abbastanza sicuro che non si limiti solo alle cose basate sulla posizione. Ma come ho detto questi problemi non sono i più facili da risolvere. Mi spiace di non poter essere di maggior aiuto. Il mio timer funzionerà all'infinito (per quanto ho visto) una cosa da controllare è stampare il backgroundTimeRemaining (non dovrebbe mai scendere ed essere molto grande) – utahwithak

0

Potrebbero esserci delle restrizioni su cosa è possibile fare in background. Prova ad aggiungere il timer al ciclo di esecuzione prima di andare in secondo piano. Anche quello potrebbe non funzionare; è possibile che l'unico codice che può essere eseguito in background sia il codice richiamato dai metodi di posizione principale ai quali ti sei registrato (ad esempio locationManager:didUpdate...). Ma la mia impressione è che i timer già in esecuzione prima di iniziare in background continueranno a funzionare.

+0

Ma questo non spiega perché se eseguo il debug funziona. Questo è quello che non capisco. Presumo che l'app si comporti allo stesso modo del debug o semplicemente eseguendo – subharb

+0

Credo che se avessi provato quello che ho suggerito (imposta il timer mentre era ancora in primo piano) avrebbe risolto il problema. In effetti, probabilmente è la stessa soluzione che hai accettato. Il tuo problema era che eri già in background e il tuo runloop aveva smesso di funzionare prima di impostare il timer. La pausa in un breakpoint e la ripresa durante lo sfondo danno al runloop una nuova possibilità di correre, quindi a quel punto il timer è stato aggiunto al runloop. È una congettura, ma credo che spieghi i fenomeni. – matt

Problemi correlati