CLMonitor does not always trigger on entry

I have an App which needs to monitor one CircularGeographicCondition for a feature. No other location services are required in the moment.

Im facing the problem that entry events aren't forwarded to my implementation in every case on real devices. In the simulator everything is working like a charm. Exit events seemed to be working quite reliable on real devices too.

Even after resuming the app from background in case of a missed entry event does not trigger the entry event. Only restarting (which recreates the monitor) triggers an entry event.

The radius of my geofence is 200 meters

What I have done:

a. Holding a service session

session = CLServiceSession(authorization: .always)

b. Creating a Task which holds the CLMonitor, adds the conditions and loops through the events.

My questions are:

  1. Is this expected behavior?
  2. If yes, how can I force the CLMonitor to recalculate the state of the condition?

Thank you so much for your help

Addition: I implemented a one time location update via CLLocationUpdate for testing purposes when the user resumes my App from background to force the system to calculate a high accuracy location.

This "workaround" indeed helped to accelerate triggering other apps which are monitoring similar geofences, but not my specific CLMonitor instance, which remains stuck.

As I mentioned already, killing and relaunching the app helps to trigger an entry event. The events date is the time of relaunching the app and not the entry time.

I am making a few REST calls inside the monitors event loop, which should only require less than one second under good conditions.

Also the testing geofence is located in an area with a lot of Wifi APs. Other Geofencing Apps which may use the old API are just working as expected.

I think CLMonitor is just completely broken actually. I am adding 14 CircularGeographicCondition's with 200m range. Some locations are at the same latitude/longitude, some are a few km away and one is in the middle of the US.

It does not detect the conditions that are at the same location and i am in The Netherlands and in the middle of the US at the same time.

I am also experiencing unreliable geofence entry & exit events since iOS 18. With iOS 17, I didn't need to use a CLServiceSession at all, now even when using one, it's unreliable. I also see the same behavior of the events timestamp to be the current time, and not the time of actual geofence entry. I made sure the app has the "Always" permission but I did not set the new NSLocationRequireExplicitServiceSession key in the Info.plist (I tested it, but couldn't see any change in the reliability)

What I am confused about is whether to start a CLServiceSession if the app is restarted in the background. Apple is not clear about it. In the WWDC session they say:

... So your job, ..., is to make sure that your process launch logic knows what features it has been tasked with pursuing, and re-takes session objects...

https://developer.apple.com/videos/play/wwdc2024/10212?time=758

But on the other hand it's also said that:

you can only start holding one (a CLServiceSession) when your app is in the foreground

https://developer.apple.com/videos/play/wwdc2024/10212?time=522

and also

... CLMonitor.events won’t yield results when it is not in use, unless a session which was started in the foreground, ....

https://developer.apple.com/videos/play/wwdc2024/10212?time=663

It is also not clear if we need to use CLLocationManager.allowsBackgroundLocationUpdates (which is documented as "Apps that receive location updates when running in the background must include the UIBackgroundModes key (with the location value) in their app’s Info.plist file"). However, in my tests, doing so didn't yield any improvement (and as I said, in iOS 17 it wasn't required either).

CLMonitor does not always trigger on entry
 
 
Q