My app is using iBeacons, and I am using func startMonitoring(for region: CLRegion)
. Then I am using func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion)
and func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion)
to run logic when user enters / exits certain Beacon CLBeaconRegion. Everything worked fine until recently, iOS 17 update I guess.
Now after I call startMonitoring(for: region) the code works for couple hours, and then it seems my app is somehow suspended and no longer able to use CoreLocation, and my code does not work, entry and exit events to beacon regions are NOT detected.
Funny enough I have some Beacon managment apps that can scan for nearby beacons, when I run one of those apps, I see on top of iPhone screen “hollow arrow” sign that marks CoreLocation being used, and then my app works for few minutes, and then again my app is suspended, and no entry/exit events into beacon regions are detected. I could figure out how to engage CoreLocation but that would rely on user intentionally opening my app, and the sole purpose of my app is to remind user when he is near one of his Beacons, so expecting user to remember to open my app defeats my apps purpose.
I added Location Updates under Background Modes for my app , maybe my app has little bit more background time until it is suspended, but the problem still persists.
So for any Beacon based app to work it should be able to monitor for nearby beacons, and run logic once beacons are detected. Any suggestions on how I could solve this?
iOS 17 CLMonitor has BeaconIdentityCondition that can match UUID, major, minor but this is only to detect we are NEAR a Beacon (entry event), what about exit event?
startMonitoring(for: region)
- fix my app so it DOES NOT get suspended, and so that this method can monitor for beacons in background with AlwaysAllow authorization?The startMonitoring(for: region)
API is still OK to use. It is supposed to work in the background provided you have Location Always permission granted. This is still true as of IOS 17.
I have also witnessed more frequent failures of iOS to fulfill the contract of the API (e.g. it doesn't wake up the app on detection 100% of the time) in recent iOS releases. But the failures are not at all universal on iOS 17 -- it usually works. And any failures are really bugs in iOS Core Location. Unfortunately, we have to rely on Apple to fix such bugs.
You can try the alternate CLMonitor
APIs, but you may find they have equivalent reliability issues. If you set up a monitor with a CLBeaconIdentityCondition
you will receive events of type
CLMonitoirngEvent
that has a state
property which will be one of these three values:
CLMonitoringStateSatisfied
CLMonitoringStateUnsatisfied
CLMonitoringStateUnknown
. A transition from Satisfied to Unsatisfied indicates that you are no longer seeing the beacons defined by the condition.