mapbox / mapbox-events-ios

Mapbox Events Framework for iOS
Other
20 stars 38 forks source link

MMELocationManagerRegionIdentifier.fence.center called at 10Hz #148

Open lefleets opened 5 years ago

lefleets commented 5 years ago

Hello!

My instance of CLLocationManager is having its delegate method didStartMonitoringFor region: CLRegion called with a region identifier of MMELocationManagerRegionIdentifier.fence.center - to me, that means it's coming from a CLLocationManager instance existing on MMELocationManager within MGLMapView.

My issue is the sheer volume of calls that are made. It happens with a period of from 1 second to 10 seconds, and in some cases it can go out of control and is called up to 10 times per second, on one device.

It's critical for me to be able to monitor region identifiers of my app in the field, which is how I noticed since my logs are almost entirely this same call. I could filter it out, but it seems like a bug to me and I wanted to share because I really love the Mapbox product and look forward to integrating it in this project for keeps.

Repro project on GitHub is here. This is my first try pushing an Xcode project repository - If you have any feedback please fire away.

Notes

  1. The issue disappears on simulator, so to reproduce you'll need to run it on a device. I've tried on an iPhone 6 and an iPhone X.
  2. The period of these calls fluctuates, but it's always present - an extra call or two wouldn't be alarming enough to open this issue, but there is no need to ask CoreLocation to monitor this region at 10Hz.

Steps to Reproduce

  1. Build and run project on a device
  2. Observe console output

Expected Behaviour

The region MMELocationManagerRegionIdentifier.fence.center should only be registered with CLLocationManager's monitoredRegions once.

Actual Behaviour

The delegate method is called as often as 10 times per second.

Configuration

julianrex commented 5 years ago

Thanks @lefleets - I'm going to transfer this issue to our https://github.com/mapbox/mapbox-events-ios/ repo and we can investigate further.

/cc @alfwatt

alfwatt commented 5 years ago

Thank you for a detailed report and test case, I agree that 10Hz updates aren't expected!

Do you ever see a region monitoring update that's not immediately preceded by a location update? In my testing I see pairs, which is what I expect, the region is updated after the location is updated but not in every update case:

2019-07-12 16:48:53.544420-0700 MMEBugRepro[57838:10983877] monitoring regions TEST, MMELocationManagerRegionIdentifier.fence.center
2019-07-12 16:48:53.546124-0700 MMEBugRepro[57838:10983877] 
<-- ISSUE ON REAL DEVICE -->
<-- Did start monitoring region MMELocationManagerRegionIdentifier.fence.center
-->
lefleets commented 5 years ago

Hi! Thanks for taking a look.

So, I'm not sure if I understand your question, but I take it that you're implying the MME region is updated with new location info when CLLocationManager delivers location updates, and then 'restarted', or 're-added' to the regions monitored (at any rate, overwriting the old MME region with the new region representing the user's new location with accompanying fence). That makes sense - correct me if I'm wrong.

Haven't seen the volume of log messages this weekend anywhere near 10Hz, but am noticing that certain devices get on a roll of logging the call which I think means the device is in motion.

So, clearly the MME region doesn't get overwritten every single time my instance of CLLocationManager gets new locations. Is this because the instance of location manager that is responsible for the MME region is configured with a different distance filter?

Novecento88 commented 5 years ago

I can confirm that I have the same exact problem. MapBox is setting a geofence with the identifier "MMELocationManagerRegionIdentifier.fence.center" continuously. I'm forced to use one less geofence (iOs let you set a maximum of 20 geofence) because of this problem. And it's power inefficient: the location manager delegate "didDetermineStateFor" is continuously called because that geofence is continuously set. Please fix this problem. It made me lose a lot of time.

rclee commented 5 years ago

@Novecento88 we use the geofence in order to save battery by preventing updates when devices aren't moving around, you can see in MMELocationManager that it's updated in response to CLLocation updates.

Depending on how your app configures it's CLLocationManager instance, the frequency of location updates can be quite high, especially when using kCLLocationAccuracyBestForNavigation and kCLDistanceFilterNone or if you have enabled startUpdatingHeading with a small value for headingFilter (the default is 1° or change in heading).

So, clearly the MME region doesn't get overwritten every single time my instance of CLLocationManager gets new locations. Is this because the instance of location manager that is responsible for the MME region is configured with a different distance filter?

@lefleets The distance filter is set by default but that should be overridden by any changes you make to the distanceFilter.

Novecento88 commented 5 years ago

How can I disable this geofence (if possible)? (Sorry if I answer this late)

rclee commented 5 years ago

@Novecento88 It is not possible to disable our geofence, it's necessary for battery savings.

If you haven't tried this already; I would recommend that you add a filter on your CLLocationManager delegate methods, using your region identifier (example). That should allow you to prevent any additional calls from affecting your code in locationManager:didDetermineState:forRegion.