My app uses region monitoring. It sets several regions and updates them dynamically.
This is done by clearing all monitored regions and setting new ones.
One problem I encountered is that clearing monitored regions is not done immediately, but apparently later in a separate thread, see here.
Since the number of monitored regions is limited by 20, I thus have to wait until property monitoredRegions
is an empty array before I can add new regions.
My idea was to use KVO to be notified when this property changes. This is done as follows (shortened version):
final class LocationManager: CLLocationManager {
static let shared = LocationManager() // Instantiate the singleton
private static var locationManagerKVOcontext = 0
private override init () {
super.init()
addObserver(self,
forKeyPath: #keyPath(monitoredRegions),
options: [],
context: &LocationManager.locationManagerKVOcontext)
}
override func observeValue(forKeyPath keyPath: String?,
of object: Any?,
change: [NSKeyValueChangeKey : Any]?,
context: UnsafeMutableRawPointer?) {
guard context == &LocationManager.locationManagerKVOcontext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
guard keyPath == #keyPath(monitoredRegions) else { return }
if monitoredRegions.isEmpty {
stopMonitoringRegionsCompletionBlock?()
}
}
With this code, I get the following build error where I use #keyPath(monitoredRegions)
:
LocationManager.swift:71:30: 'monitoredRegions' is unavailable
/CoreLocation.CLLocationManager:50:14: 'monitoredRegions' has been explicitly marked unavailable here
If I replace #keyPath(monitoredRegions)
by “monitoredRegions“
, I can build the app since the compiler cannot check the validity of the keyPath, but monitoredRegions
is not observed, i.e. the func observeValue
is not called.
So it seems to me that key value observing of monitoredRegions
is not possible.
My questions are:
Is my code in principle correct or is there a workaround?
PS: I guess I could poll this property by myself, but this seems to be ugly.
Edit:
I implemented polling to have any solution, and to get an order of magnitude how long it takes to clear monitored regions.
In my case it takes between 0.2 and 1.4 seconds until all monitored regions are cleared. This time surely depends on how many regions have to be cleared.