summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wray <jason@mapbox.com>2016-01-20 20:04:12 -0500
committerJason Wray <jason@mapbox.com>2016-02-19 13:14:54 -0500
commit15b9f3171a1c41d5a4c2b454fcce9b92350e28f2 (patch)
treee6325ac2d781ccf6a0aa8e0daa54401fe0c4ed3a
parent9f4e8dd676a61289361ed8a0a79bd6582a6854d5 (diff)
downloadqtlocation-mapboxgl-15b9f3171a1c41d5a4c2b454fcce9b92350e28f2.tar.gz
[ios] Refactor MGLMapView's location services
- Pause location services when the app goes to sleep; address iOS 8 blue bar issue. - Only ask for location permissions if not already granted/denied. - Cleanup usage of `.isDormant` → `.dormant` Partially addresses #2945, for which a full and complete fix waits until #4030.
-rw-r--r--platform/ios/src/MGLMapView.mm73
1 files changed, 44 insertions, 29 deletions
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index c4f6cd39a3..83904f168f 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -760,7 +760,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
// This is the delegate of the GLKView object's display call.
- (void)glkView:(__unused GLKView *)view drawInRect:(__unused CGRect)rect
{
- if ( ! self.isDormant)
+ if ( ! self.dormant)
{
CGFloat zoomFactor = _mbglMap->getMaxZoom() - _mbglMap->getMinZoom() + 1;
CGFloat cpuFactor = (CGFloat)[[NSProcessInfo processInfo] processorCount];
@@ -906,7 +906,7 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
{
MGLAssertIsMainThread();
- if ( ! self.isDormant)
+ if ( ! self.dormant)
{
[self validateDisplayLink];
self.dormant = YES;
@@ -957,6 +957,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
{
self.dormant = YES;
+ [self validateLocationServices];
+
[MGLMapboxEvents flush];
_displayLink.paused = YES;
@@ -1006,6 +1008,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
_mbglMap->resume();
_displayLink.paused = NO;
+
+ [self validateLocationServices];
}
}
@@ -3022,45 +3026,31 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
#pragma mark - User Location -
-- (void)setShowsUserLocation:(BOOL)showsUserLocation
+- (void)validateLocationServices
{
- if (showsUserLocation == _showsUserLocation || _isTargetingInterfaceBuilder) return;
+ BOOL shouldEnableLocationServices = self.showsUserLocation && !self.dormant;
- _showsUserLocation = showsUserLocation;
-
- if (showsUserLocation)
+ if (shouldEnableLocationServices && ! self.locationManager)
{
- if ([self.delegate respondsToSelector:@selector(mapViewWillStartLocatingUser:)])
- {
- [self.delegate mapViewWillStartLocatingUser:self];
- }
-
- self.userLocationAnnotationView = [[MGLUserLocationAnnotationView alloc] initInMapView:self];
- self.userLocationAnnotationView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
- UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
-
- self.locationManager = [CLLocationManager new];
+ self.locationManager = [[CLLocationManager alloc] init];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
- // enable iOS 8+ location authorization API
- //
- if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)])
+ if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)
{
- BOOL hasLocationDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"] ||
- [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"];
+ BOOL hasLocationDescription = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"] || [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"];
if (!hasLocationDescription)
{
[NSException raise:@"Missing Location Services usage description" format:
- @"In iOS 8 and above, this app must have a value for NSLocationWhenInUseUsageDescription or NSLocationAlwaysUsageDescription in its Info.plist."];
+ @"In iOS 8 and above, this app must have a value for NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription in its Info.plist."];
}
- // request location permissions, if both keys exist ask for less permissive
- if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"])
+
+ if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"])
{
- [self.locationManager requestWhenInUseAuthorization];
+ [self.locationManager requestAlwaysAuthorization];
}
- else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationAlwaysUsageDescription"])
+ else if ([[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"])
{
- [self.locationManager requestAlwaysAuthorization];
+ [self.locationManager requestWhenInUseAuthorization];
}
}
#endif
@@ -3069,12 +3059,37 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
}
- else
+ else if ( ! shouldEnableLocationServices && self.locationManager)
{
[self.locationManager stopUpdatingLocation];
[self.locationManager stopUpdatingHeading];
self.locationManager.delegate = nil;
self.locationManager = nil;
+ }
+}
+
+- (void)setShowsUserLocation:(BOOL)showsUserLocation
+{
+ if (showsUserLocation == _showsUserLocation || _isTargetingInterfaceBuilder) return;
+
+ _showsUserLocation = showsUserLocation;
+
+ if (showsUserLocation)
+ {
+ if ([self.delegate respondsToSelector:@selector(mapViewWillStartLocatingUser:)])
+ {
+ [self.delegate mapViewWillStartLocatingUser:self];
+ }
+
+ self.userLocationAnnotationView = [[MGLUserLocationAnnotationView alloc] initInMapView:self];
+ self.userLocationAnnotationView.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin |
+ UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin);
+
+ [self validateLocationServices];
+ }
+ else
+ {
+ [self validateLocationServices];
if ([self.delegate respondsToSelector:@selector(mapViewDidStopLocatingUser:)])
{