How iOS background tracking works
iOS has no equivalent of an Android foreground service. An app stays alive in the background for one of a few reasons, and for location tracking the reason is: location updates are running. So Long Ping keeps them running for as long as tracking is on, and controls cost by changing how precise they are, not by switching them off.
While tracking is on
Section titled “While tracking is on”- Standard location updates run the whole time, with
allowsBackgroundLocationUpdates = true(only ifUIBackgroundModescontainslocation),pausesLocationUpdatesAutomatically = falseand no distance filter. ios.activityType(default'automotive') andios.showsBackgroundLocationIndicator(defaultfalse) are passed to CoreLocation.- Significant-change monitoring is on as a safety net.
- Fixes are recorded on your clock; everything between is ignored.
Low-power mode between fixes
Section titled “Low-power mode between fixes”When the effective interval is 60 s or more, Long Ping asks CoreLocation for 3 km accuracy between fixes,
which lets the GPS rest. 15 s before the next fix is due it switches to your configured accuracy
(high → Best, balanced → HundredMeters, low → Kilometer), records the fix, and drops back.
Below 60 s the configured accuracy stays on the whole time: there isn’t enough time between fixes for the switch to pay off.
Parked
Section titled “Parked”When the device parks, Long Ping also monitors a circular region around the parked position (radius
max(100, stopRadiusM × 2), exit only). Leaving it switches to moving immediately and is one of the ways iOS
can relaunch a terminated app. The region is removed when the device moves again or tracking stops.
When the app is swiped away
Section titled “When the app is swiped away”With the default stopOnTerminate: false, Long Ping makes sure significant-change and region monitoring are on
as the app terminates. If it was moving, it also puts a region around the last position, so the relaunch comes
sooner than significant-change alone would bring it. When the device then moves far enough, iOS relaunches the
app in the background. Long Ping registers for app launch in native code and resumes tracking before your
JavaScript loads, if tracking was enabled and permission still allows it. No start() call needed.
What it means in practice: a swipe-away while parked loses the parked fixes until the van drives off; a swipe-away while driving loses fixes until iOS relaunches the app, typically within a few hundred meters.
Set stopOnTerminate: true if you’d rather a swipe-away stopped tracking for good.
Reboots
Section titled “Reboots”After a reboot, an app that was tracking comes back the same way: on movement, iOS relaunches it and the engine resumes. If that happens before the phone’s first unlock, when the app’s saved state can’t be read yet, the engine logs it and resumes as soon as the phone is unlocked.
Permissions that change behaviour
Section titled “Permissions that change behaviour”- “While Using” instead of “Always”: the relaunch paths above (significant-change and region monitoring)
need “Always”. For fleet use, ask for
'always'; see Permissions. If tracking is enabled but permission is missing at launch, the engine logs it and waits (and emits anerrorevent withPERMISSION_DENIEDif JavaScript is listening). - Precise Location off: fixes come with reduced accuracy (
getProviderState().accuracyAuthorization === 'reduced'). With the defaultminAccuracyM: 100, many of them may be filtered out; the overdue rule still records the best available fix when one is late. - Low Power Mode: reported as
powerSaveModeingetProviderState().
Other details
Section titled “Other details”- Uploads run on a serial queue with
URLSession, wrapped in a background task so they finish when the app is suspended mid-request. - The queue is a SQLite file in Application Support, excluded from backups. Credentials are in the Keychain, wiped on the first launch after a (re)install.
getCurrentPosition()resolves early once a fix reaches 20 / 100 / 1000 m accuracy forhigh/balanced/low.