iOS stops background location updates because it suspends your app, not because Core Location fails. Unless the app declares the location background mode, enables background updates on its CLLocationManagerPerché iOS interrompe gli aggiornamenti di localizzazione in background nei Capacitor app: sospensione, modalità di background, autorizzazione, pausa automatica, accuratezza e come risolvere ogni causa. @capgo/background-geolocation Crediti dell'articolo
How iOS gestisce un'applicazione in background
When a user sposta la home o blocca lo smartphone, iOS dà all'applicazione un breve tempo, poi la sospende. Un'applicazione sospesa non riceve tempo di CPU. Per un'applicazione Capacitor questo significa che sia il lato nativo che il WebView smettono di funzionare, quindi anche il callback JavaScript non si attiva più.
Apple fa un'eccezione per le app che utilizzano attivamente la posizione. Se l'app è configurata per la posizione in background e ha una sessione di posizione attiva iniziata in foreground, iOS la tiene in esecuzione e continua a fornire aggiornamenti. Tutto ciò che segue riguarda il rispetto di quel contratto, e i casi in cui il sistema lo rompe di proposito.
Causa 1: la modalità di background della posizione manca
Senza location in UIBackgroundModes, nessuna quantità di code farà fluire gli aggiornamenti. Aggiungilo a ios/App/App/Info.plist:
<key>UIBackgroundModes</key>
<array>
<string>location</string>
</array>
Si può anche abilitarlo in Xcode sotto Signing & Capabilità, Modalità di background, Aggiornamenti della posizione. È una chiave plist, non un'autorizzazione, quindi non è necessario modificare il profilo di provisioning.
La proprietà nativa dietro di esso è allowsBackgroundLocationUpdates. Impostarlo su true senza la modalità di background nel plist fa bloccare l'app. Il plugin Capgo lo imposta per te quando passi backgroundMessage a start()Quindi la chiave plist deve essere presente prima di distribuire l'app.
La verifica di App Review verifica che il background mode sia giustificato. Spiega nelle note della revisione quale feature lo utilizza e assicurati che la feature sia visibile al revisore.
Causa 2: gli aggiornamenti sono stati avviati dal background
Apple’s rule: background updates continue if they were started while the app was in the foreground. Trying to start a session from a silent push, a background fetch or a BGTaskScheduler Inizia a tracciare da un'azione dell'utente o al riavvio dell'app:
Inizia la tracciatura da un'azione dell'utente o alla ripresa dell'app:
import { App } from '@capacitor/app';
import { BackgroundGeolocation } from '@capgo/background-geolocation';
let tracking = false;
export async function startTracking() {
if (tracking) return;
tracking = true;
await BackgroundGeolocation.start(
{
backgroundMessage: 'Recording your route',
backgroundTitle: 'Route recording',
requestPermissions: true,
distanceFilter: 10,
url: 'https://api.example.com/v1/points',
},
(location, error) => {
if (error) return console.error(error);
if (location) console.log(location.latitude, location.longitude);
},
);
}
// Re-arm when the user comes back, if the session should be active
App.addListener('appStateChange', ({ isActive }) => {
if (isActive && shouldBeTracking()) startTracking();
});
declare function shouldBeTracking(): boolean;
Causa 3: backgroundMessage non è stato passato
Questo è specifico per il plugin Capgo e il bug più comune segnalato. Se backgroundMessage se __CAPGO_KEEP_0__ è indefinito, il plugin configura il manager di posizione per l'uso in primo piano solo. allowsBackgroundLocationUpdates stays false Passa un messaggio su entrambe le piattaforme. Su Android diventa anche il testo della notifica del servizio di background.
Motivo 4: il livello di autorizzazione sbagliato, o Consentisci una volta
Molti sviluppatori pensano di dover utilizzare sempre per tracciare in background. Non è così. Apple documenta che un'app con l'autorizzazione When In Use continua a funzionare in background mentre ha servizi di localizzazione attivi, fintanto che gli aggiornamenti in background sono abilitati.
Always conta per qualcos'altro: il riavvio di un'app terminata. Solo la monitorizzazione di regione, la localizzazione significativa e le visite possono riavviare un'app, e solo con Always.
Two user choices quietly break background tracking:
- Consenti una volta. Questo è un permesso When In Use temporaneo che scade quando l'app smette di essere utilizzata. La prossima sessione inizia da “non determinato” di nuovo.
- Mentre si utilizza, poi mostra sempre la richiesta di Always. Quando richiedi Always, iOS potrebbe mostrare la richiesta di aggiornamento in un momento che sceglie, spesso quando l'app non è sullo schermo.
Controlla lo stato reale prima di iniziare una sessione:
import { BackgroundGeolocation } from '@capgo/background-geolocation';
const status = await BackgroundGeolocation.checkPermissions();
if (status.location !== 'granted') {
await BackgroundGeolocation.requestPermissions({ permissions: ['location'] });
}
if (status.backgroundLocation === 'when_in_use') {
// Background tracking still works for standard updates.
// Explain why Always helps if you also rely on geofences.
}
Sul iOS, backgroundLocation ritorna when_in_use or granted / alwaysQuindi, puoi mostrare la spiegazione giusta al posto di indovinare.
Causa 5: Core Location sospende gli aggiornamenti automaticamente.
CLLocationManager.pausesLocationUpdatesAutomatically predefinito a true. Quando iOS decide che l'utente non si sta muovendo, sospende gli aggiornamenti per risparmiare la batteria. Per un'applicazione 'Usa quando in uso', una sospensione interrompe l'accesso alla posizione fino a quando l'app non viene lanciata nuovamente, e Core Location non riprende da solo.
Il plugin Capgo imposta pausesLocationUpdatesAutomatically = false in suo proprio code, quindi questo viene gestito. Se scrivi il tuo proprio code nativo, o utilizzi un altro plugin, controlla questa proprietà prima.
Causa 6: il dispositivo è fermo e il filtro è grande
Con un distanceFilter di 50 metri, un telefono che sta sulla scrivania non produce aggiornamenti. Questo sembra 'la tracciatura fermata' nei tuoi log, ma funziona come progettato.
- Se hai bisogno di heartbeats mentre sei fermo, utilizza un piccolo o zero
distanceFilter. - Usa
minIntervalMsLimitare la frequenza con cui vengono inviate le POST native, piuttosto che un filtro di distanza ampio.
await BackgroundGeolocation.start(
{
backgroundMessage: 'Vehicle tracking active',
distanceFilter: 0,
minIntervalMs: 120_000, // at most one native POST every 2 minutes
url: 'https://api.example.com/v1/vehicle-points',
},
() => {},
);
Motivo 7: Localizzazione Precisa è disattivata
Since iOS 14 users can turn off Precise Location for your app. You still get updates, but they are approximate (several kilometers) and arrive much less often. Detect this in your data (large accuracy values) and explain to the user why precise location matters for your feature. If you ship a delivery or fitness app, show this in onboarding, not after a bad trip.
Causa 8: l'utente ha terminato l'app
If the user swipes the app away in the app switcher, iOS stops standard location updates. No plugin can keep them running. This is a common surprise for teams coming from Android, where a foreground service can keep running after the task is removed.
Options:
- Non forzare l'uscita dall'applicazione durante una sessione. La maggior parte delle app per flotte lo fa durante l'onboarding.
- Inviare una notifica per ricordare all'utente di riaprire l'app quando il tuo server smette di ricevere punti per una sessione.
- Invia una notifica per ricordare all'utente di riaprire l'app quando il tuo server smette di ricevere punti per una sessione.
Causa 9: Non viene eseguito JavaScript anche se il nativo è attivo
A subtle one. Native code can receive a location while the WebView is suspended, or while it is still alive but not processing timers or network calls quickly. If you send points with fetch potrebbero arrivare in ritardo o non arrivare affatto.
Usa l'opzione del plugin. url Ogni punto viene inviato da code nativo con lo stesso JSON del tipo più Location tipo più "source": "native", independent of the WebView. Keep the callback for UI updates only. Delivery is best effort with no on-disk queue, so if you cannot lose a point, also store it locally when the callback fires and reconcile later.
come funzionano le attività di background in __CAPGO_KEEP_0__ Come funzionano le attività di background in Capacitor e vedi @capgo/capacitor-background-task.
Causa 10: Modalità Energia Ridotta e stato termico
Low Power Mode reduces background activity across the system. Location still works, but other things your session depends on (network retries, background refresh) slow down. Test with Low Power Mode on before you sign off a release.
L'indicatore blu
When an app with When In Use authorization uses location in the background, iOS shows a blue pill in the status bar. The Capgo plugin sets showsBackgroundLocationIndicator to true per le sessioni di background, ciò che gli utenti si aspettano e che i revisori cercano. Non cercare di nasconderlo, gli utenti ci hanno fiducia.
Un piano di test che catturi questi bug
La prova con il simulatore non è sufficiente per la posizione di background. Utilizza un iPhone reale e:
- Costruisci una configurazione di rilascio, non solo debug. Le costruzioni di debug attaccate a Xcode ricevono un trattamento di ciclo di vita diverso.
- Inizia una sessione in primo piano, blocca il telefono, cammina o guida per 20 minuti.
- Ripeti con “Consenti una volta”, con la posizione precisa disattivata, con il Modalità bassa potenza attivata.
- Controlla i tuoi log del server per
source: "native"punti, non solo i tuoi log in-app. - Forza l'uscita durante una sessione e conferma che il tuo app spieghi cosa è successo alla prossima avviatura.
Se hai bisogno di un ID dispositivo per costruzioni ad hoc, il trova l'ID dispositivo iOS lo ottiene da Safari. Se non hai un Mac con Xcode 26 per le costruzioni, Capgo Costruzione può produrre build iOS firmate nel cloud.
Elenco di controllo di risoluzione dei problemi
| Sintomo | Causa probabile | Soluzione |
|---|---|---|
| Si ferma dopo pochi secondi di chiusura | No location modalità di background o nessuna backgroundMessage |
Aggiungi la chiave plist e passa backgroundMessage |
| Crash al avvio | allowsBackgroundLocationUpdates senza modalità di background |
Aggiungi UIBackgroundModes → location |
| Lavora una volta, poi non più | L'utente ha scelto di consentire una volta | Spiega e chiedi nuovamente, o invia a openSettings() |
| Smette quando parcheggiato | Grande distanceFilter |
Abbassalo, utilizza minIntervalMs |
| Punti lontani, bassa accuratezza | Posizione precisa spenta | Chiedi all'utente di abilitarlo |
| Smette dopo swipe via | L'utente ha terminato l'app | Si aspetta su iOS, utilizza geofrancesi per il riavvio |
| Native riceve punti, il server no | JavaScript fetch in callback |
Utilizza il url opzione |
Risoluzione dei problemi di spedizione
La maggior parte di questi fix toccano Info.plist o la configurazione nativa, quindi richiedono una nuova versione del negozio App Store. Le parti JavaScript, come le spiegazioni delle autorizzazioni, il testo di onboarding e la logica di riprova, possono essere spediti agli utenti esistenti con Capgo aggiornamenti live una volta che la versione nativa è stata rilasciata.
Se stai decidendo tra plugin, la nostra comparazione di Transistorsoft e il plugin gratuito Capgo copre le trade-off.