CLLocationManager: request for a maritime/sailing CLActivityType (low-acceleration, continuous-motion use case)

We 7develop a location-tracking backend for sailing regatta tracking (RegattaHero, GPS tracking of racing sailboats via a Flutter iOS app). We rely on CLLocationManager for continuous position updates during races that can last several hours.

Problem: In light wind conditions, a sailboat can move at low but steady speed (e.g. 1-2 knots) with essentially no acceleration signature - unlike automotive or fitness activities, which involve intermittent acceleration/deceleration (starting, braking, footstrikes). We suspect Core Location's motion-based heuristics (built on accelerometer/motion coprocessor data, not solely GPS delta) interpret this near-constant, low-acceleration motion as "stationary" or low-priority, resulting in reduced update frequency or unexpected pausing of location updates.

We have already set pausesLocationUpdatesAutomatically = false explicitly, which per documentation should prevent automatic pausing entirely - but we still observe degraded update behavior in these conditions. This suggests the effect is not limited to the auto-pause mechanism but also influences other parts of the positioning/update-frequency pipeline that key off activityType.

We currently use activityType = .otherNavigation (the closest existing match, covering "boats" alongside cycling/trains/off-road vehicles), but this activity type appears tuned around vehicles with more typical acceleration profiles, not low-speed, low-acceleration marine drift.

Steps to Reproduce:

  1. Set activityType = .otherNavigation, pausesLocationUpdatesAutomatically = false, desiredAccuracy = kCLLocationAccuracyBestForNavigation
  2. Track a device moving continuously at 1-3 knots with minimal acceleration variance (e.g. sailboat drifting/sailing in light wind, or equivalent slow, smooth continuous motion) over an extended period (30+ minutes)
  3. Compare update frequency/consistency to a scenario with typical stop-and-go motion (e.g. driving in traffic)

Expected: Consistent location update delivery reflecting actual continuous movement, independent of acceleration variance, when pausesLocationUpdatesAutomatically is explicitly disabled.

Actual: Update frequency/consistency appears to degrade during sustained low-acceleration, low-to-moderate-speed motion at sea, despite auto-pause being disabled.

Suggestion: Either: (a) Add a dedicated CLActivityType case for marine/nautical navigation, with pause/throttling heuristics based on speed-over-ground rather than acceleration signatures, or (b) Document/expose a way to fully decouple update-frequency behavior from the motion-coprocessor-based heuristic when pausesLocationUpdatesAutomatically = false is set, so this flag reliably covers all related throttling behavior, not just the auto-pause feature itself.

Apparently, Apple has granted your wish :-)

iOS 27 added an activity type for this: CLActivityType.maritime, with a matching CLLocationUpdate.LiveConfiguration.maritime for live updates. Apple's documentation describes it as positioning for "activities in vessels on water, including while anchored", and the comment in CLLocationUpdater.h says it is "tuned for vehicular maritime use cases". It came without a WWDC session or a release note, so it is easy to miss.

Set .maritime on iOS 27 and later, and keep .otherNavigation for earlier systems:

if #available(iOS 27, *) {
    manager.activityType = .maritime
} else {
    manager.activityType = .otherNavigation
}

Since you are on Flutter: if your location plugin maps activity types to its own enum, it will not offer .maritime until it is updated, and you may need to set it from native code.

I would retest your light-wind tracks with it before going further. If you still see the same behaviour, filing a Feedback with a sysdiagnose taken after installing the Location Services logging profile would be the next step.

I have a note at 7strikes.dev that covers the live updates version as well.

--- S.Beck -- 7strikes.dev