Comportamento per l'API di posizione di modifica significativa in caso di interruzione / sospensione?


108

Questa è la sezione della documentazione di CLLocationManager che descrive il comportamento dell'app con startMonitoringSignificantLocationChanges :

Se avvii questo servizio e la tua applicazione viene successivamente chiusa, il sistema riavvia automaticamente l'applicazione in background se arriva un nuovo evento. In tal caso, il dizionario delle opzioni passato all'applicazione: didFinishLaunchingWithOptions: il metodo del delegato dell'applicazione contiene la chiave UIApplicationLaunchOptionsLocationKey per indicare che l'applicazione è stata avviata a causa di un evento di posizione. Al riavvio, è comunque necessario configurare un oggetto gestore di posizione e chiamare questo metodo per continuare a ricevere eventi di posizione. Quando si riavvia i servizi di localizzazione, l'evento corrente viene consegnato immediatamente al delegato. Inoltre, la proprietà della posizione dell'oggetto del gestore della posizione viene popolata con l'oggetto della posizione più recente anche prima di avviare i servizi di posizione.

Quindi la mia comprensione è che se la tua app termina (e presumo se non chiami stopMonitoringSignificantLocationChanges da applicationWillTerminate ) verrai svegliato con un parametro UIApplicationLaunchOptionsLocationKey per application: didFinishLaunchingWithOptions . A quel punto crei il tuo CLLocationManager , chiama startMonitoringSignificantLocationChanges ed esegui l'elaborazione della posizione in background per un periodo di tempo limitato . Quindi sto bene con questo pezzo.

Il paragrafo precedente parla solo di cosa succede quando l'app viene chiusa, non suggerisce cosa fare quando l'applicazione viene sospesa. La documentazione per didFinishLaunchingWithOptions dice:

L'applicazione tiene traccia degli aggiornamenti della posizione in background, è stata eliminata e ora è stata riavviata. In questo caso, il dizionario contiene una chiave che indica che l'applicazione è stata riavviata a causa di un nuovo evento di posizione.

Suggerendo che riceverai questa chiamata solo quando la tua app verrà avviata (a causa di un cambio di posizione) dopo essere stato terminato.

Tuttavia, il paragrafo sul Servizio di cambiamento significativo nella Guida alla programmazione per la conoscenza della posizione ha quanto segue da dire:

Se lasci questo servizio in esecuzione e la tua applicazione viene successivamente sospesa o terminata, il servizio riattiva automaticamente l'applicazione quando arrivano nuovi dati sulla posizione. Al momento della sveglia, la tua applicazione viene messa in background e ha poco tempo per elaborare i dati sulla posizione. Poiché l'applicazione è in background, dovrebbe svolgere un lavoro minimo ed evitare qualsiasi attività (come l'interrogazione della rete) che potrebbe impedirne il ritorno prima della scadenza del tempo assegnato. In caso contrario, l'applicazione potrebbe essere chiusa.

Ciò suggerisce che sei svegliato con i dati sulla posizione se la tua app è stata sospesa, ma non menziona come sei stato svegliato:

Nel processo di stesura di questo, penso di aver appena risposto alla mia domanda, ma sarebbe fantastico se la mia comprensione di ciò fosse confermata da qualcuno più informato.

Risposte:


80

Da quando ho posto questa domanda, ho fatto un bel po 'di test (principalmente sul treno tra casa e lavoro) e ho confermato che il comportamento per le app sospese è come sospettavo alla fine della domanda.

Ovvero, la tua app sospesa viene riattivata, non ricevi alcuna richiamata sul delegato dell'app, ma ricevi gli aggiornamenti sulla posizione tramite il tuo CLLocationManagerDelegate esistente . È possibile rilevare che si è in esecuzione in background controllando applicationState e svolgere un lavoro limitato nel caso in cui si venga svegliati da uno stato sospeso per eseguire l'elaborazione della posizione.

[UIApplication sharedApplication].applicationState == UIApplicationStateBackground

Sono giunto a questa conclusione con un cablaggio per il test di posizione che puoi scaricare e provare. È un'app piuttosto semplice che ti consente di attivare modifiche significative e API di modifica GPS tramite l'interfaccia utente e registrare tutte le risposte che ricevi.

NB Il punto sei della risposta precedente non è corretto. Le app sospese congelate ricevono callback CLLocationManagerDelegate quando vengono riattivate da uno stato sospeso.


1
Ha colpito il numero 6 nella mia risposta per non confondere le persone.
Aaron

Ironia della sorte, ho anche sentito la stessa confusione durante lo sviluppo per il cambiamento significativo. Ho ancora qualche dubbio su cosa succede se l'app viene chiusa. il callback di UIApplicationDelegate non verrà eseguito? è il modo giusto per avviare l'app. se il location manager non è ancora stato attivato, come può ricevere le notifiche in background? (tempo per un po 'di ricerca e sviluppo)
darshansonde

Grazie mille per l'app di esempio, è stata molto utile per me. Ho una domanda: cosa succede se stavo utilizzando il servizio di localizzazione standard in background, non quello significativo, l'app verrà riavviata anche dopo la chiusura in quel caso? Ho fatto questa domanda qui in dettaglio, sarei felice se potesse alleggerire:] stackoverflow.com/questions/12239967/...
aslisabanci


Sai quanto tempo è passato alla chiusura della tua app? E poi ottenere invece una richiamata appDelegate? (Sono tipo 30 minuti? 2 ore? 5 ore?) Il motivo per cui lo chiedo è perché ho impostato una regione da monitorare. Ho provato molte volte a vedere la mia app lanciata, ma solo una volta ho avuto modo di riavviare l'app. Le altre volte la didExitRegionrichiamata ma non sono stato in grado di farlo startLocationUpdatesda lì perché non era tramite il lancio dell'app ...
Honey

25

La mia comprensione è la seguente (sto scrivendo un'applicazione che si basa su questa API, ma non ho completato questo componente abbastanza per iniziare il test):

  1. La tua applicazione viene eseguita per la prima volta, ti registri a startMonitoringSignificantLocationChanges e fornisci una funzione di callback. Mentre l'applicazione è in esecuzione, chiamerà la richiamata ogni volta che riceve una modifica significativa.
  2. Se la tua applicazione viene messa in background, UIApplication riceverà applicationWillResignActive , seguita da applicationDidEnterBackground .
  3. Se la tua applicazione viene terminata mentre è sospesa in background, non riceverai alcuna notifica; tuttavia, se la tua applicazione viene terminata mentre è in esecuzione (in primo piano o in background per quanto ne so), avrai un momento con applicationWillTerminate . Non è possibile richiedere tempo in background aggiuntivo da questa funzione.
  4. Nonostante venga interrotto in background, il sistema operativo riavvierà l'applicazione. Se la tua applicazione viene semplicemente lanciata dal sistema operativo per una modifica, riceverai una chiamata all'applicazione didFinishLaunchingWithOptions :

    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey])

    ti aiuterà a determinare se sei tornato da una modifica della posizione in background.

  5. Se invece eri attualmente in esecuzione in background e la tua app viene riavviata manualmente dall'utente, riceverai un'applicazioneWillEnterForeground seguita da applicationDidBecomeActive .
  6. Indipendentemente da come è successo, quando la tua applicazione viene riavviata (a meno che non fosse ancora in esecuzione in background come risultato di un'attività in background e detta attività avesse iniziato a monitorare le modifiche), devi dirle esplicitamente di avviare di nuovoMonitoringSignificantLocationChanges perché il callback è no attaccati più a lungo dopo "liofilizzazione". E sì, devi solo implementare il codice in didUpdateToLocation dopo aver ricollegato un gestore di posizione di qualche tipo una volta tornato dallo stato sospeso.

Questo è quello che sto facendo con il mio sviluppo del codice in questo momento. Come ho detto prima, non sono ancora pronto per testarlo su un dispositivo, quindi non posso dire se ho interpretato tutto correttamente, quindi commentatori, non esitate a correggermi (anche se ho fatto una lettura sostanziale sul argomento).

Oh, e se per qualche colpo di sfortuna rilasci un'app che fa quello che voglio che faccia la mia, potrei piangere :)

In bocca al lupo!


1
@Tegeril +1 Grazie per la risposta. Stavo iniziando a sentire i grilli su questo. :) Sono sorpreso che le app che hanno iniziato a essere sospese debbano richiamare startMonitoringSignificantLocationChanges. Hai un link al documento in cui è descritto? La mia comprensione era che il caricamento da uno stato sospeso creerà un'istanza di tutti i tuoi oggetti come erano quando l'app è stata sospesa. Quindi mi aspetto che la richiesta di modifica significativa sia in vigore.
RedBlueThing

Potresti parlare di questo? "Al riavvio, è comunque necessario configurare un oggetto gestore di posizione e chiamare questo metodo per continuare a ricevere eventi di posizione" Ma penso che questo si riferisca al caso in cui l'app è stata avviata da uno stato terminato (da un evento di posizione). Questa è fondamentalmente la radice della mia domanda, "cosa succede per il caso sospeso?".
RedBlueThing

Morgan Grainger sui forum Dev ha suggerito questo: "È necessario creare un CLLocationManager, impostare un delegato e chiamare startMonitoringSignificantLocationChanges all'avvio dell'applicazione, altrimenti Core Location non avrà un posto dove fornire gli aggiornamenti". nel contesto del riavvio di un'applicazione indipendentemente dallo stato terminato o sospeso. Da "l'app è stata rilanciata dopo startMonitoringSignificantLocationChanges e ora cosa?"
Aaron

Sono d'accordo che questo potrebbe essere ancora vago anche nel contesto di quel post sul forum (il poster stava discutendo del risveglio dallo sfondo, ma Morgan ha utilizzato il riavvio più generale di un'applicazione). Continuo a pensare che devi chiamare di nuovo per monitorare quando la tua applicazione viene riavviata se vuoi lavorare con la funzione di modifiche significative. Se invece desideri avviare un'attività in background e aggiornare con il servizio di localizzazione standard e la funzionalità GPS, questa è un'opzione alternativa. Non credo che sia necessario registrarsi nuovamente a ogni lancio con modifiche significative per poter essere lanciato di nuovo.
Aaron

1
Sono contento che ne sia uscito qualcosa di definitivo, dovrebbe aiutarmi in futuro :)
Aaron

1

Se l'applicazione viene richiamata dallo stato sospeso a seguito del cambio di posizione, l'applicazione verrà avviata in background.

Tutti gli oggetti saranno attivi e riceverai l'aggiornamento della posizione nel delegato esistente.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.