Geofencing with CLMonitor Does Not Work After User-Initiated Task Kill

I have implemented geofencing using CLMonitor. The implementation follows this general structure:

private var monitorTask: Task<Void, Never>?
private var backgroundSession: CLBackgroundActivitySession?

func start() async {
  backgroundSession = CLBackgroundActivitySession()
  monitorTask = Task {
    do {
      let monitor = await CLMonitor("monitor")
      for try await event in await monitor.events {
        handleEvent(event: event)
      }
    } catch {}
  }
}

func addSpot() async {
  let monitor = await CLMonitor("monitor")
  let center = CLLocationCoordinate2D(latitude: 0, longitude: 0)
  let condition = CLMonitor.CircularGeographicCondition(center: center, radius: 100)
  await monitor.add(condition, identifier: "sample-1")
}

When the app is not task-killed, the code inside handleEvent executes as expected. However, after a user-initiated task kill, the functionality does not work properly.

The two common causes for this that we see are:

1- Invalidating the CLBackgroundActivitySession some time the app has been killed

2- Not properly joining the existing CLBackgroundActivitySession from the last session by recreating one when launched in the background.

Make sure you are not releasing or overwriting your backgroundSession variable. And make sure your code recreates the CLBackgroundActivitySession when it gets relaunched in the background without relying on a code path involving UI actions.


Argun Tekant /  DTS Engineer / Core Technologies

Geofencing with CLMonitor Does Not Work After User-Initiated Task Kill
 
 
Q