From c42e83fcc6f888373c318ee9aa2e5f0c28e7d970 Mon Sep 17 00:00:00 2001 From: Brad Leege Date: Fri, 20 Mar 2015 11:11:06 -0500 Subject: #1033 - Moving MBLocationManager to Core GL from app specific instance. --- gyp/platform-ios.gypi | 2 + include/mbgl/ios/MBLocationManager.h | 24 ++++++ ios/app/MBLocationManager.h | 24 ------ ios/app/MBLocationManager.m | 142 ----------------------------------- ios/app/MBXViewController.mm | 2 - platform/ios/MBLocationManager.m | 142 +++++++++++++++++++++++++++++++++++ platform/ios/MGLMapView.mm | 5 ++ styles | 2 +- 8 files changed, 174 insertions(+), 169 deletions(-) create mode 100644 include/mbgl/ios/MBLocationManager.h delete mode 100644 ios/app/MBLocationManager.h delete mode 100644 ios/app/MBLocationManager.m create mode 100644 platform/ios/MBLocationManager.m diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index a8a827af65..f3191659a5 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -16,6 +16,8 @@ '../platform/darwin/asset_root.mm', '../platform/darwin/image.mm', '../platform/darwin/reachability.m', + '../include/mbgl/ios/MBLocationManager.h', + '../platform/ios/MBLocationManager.m', '../include/mbgl/ios/MGLMapView.h', '../platform/ios/MGLMapView.mm', '../include/mbgl/ios/MGLStyleFunctionValue.h', diff --git a/include/mbgl/ios/MBLocationManager.h b/include/mbgl/ios/MBLocationManager.h new file mode 100644 index 0000000000..84a847c9e7 --- /dev/null +++ b/include/mbgl/ios/MBLocationManager.h @@ -0,0 +1,24 @@ +// +// MBLocationManager.h +// Hermes +// +// Created by Brad Leege on 3/8/15. +// Copyright (c) 2015 Mapbox. All rights reserved. +// + +#import +#import "CoreLocation/CoreLocation.h" + +@interface MBLocationManager : NSObject + ++ (id)sharedManager; + +- (BOOL) isAuthorizedStatusDetermined; +- (void) requestAlwaysAuthorization; + +- (void) startUpdatingLocation; +- (void) stopUpdatingLocation; + +- (void) setBackgroundStatus:(BOOL)isBackground; + +@end diff --git a/ios/app/MBLocationManager.h b/ios/app/MBLocationManager.h deleted file mode 100644 index 84a847c9e7..0000000000 --- a/ios/app/MBLocationManager.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// MBLocationManager.h -// Hermes -// -// Created by Brad Leege on 3/8/15. -// Copyright (c) 2015 Mapbox. All rights reserved. -// - -#import -#import "CoreLocation/CoreLocation.h" - -@interface MBLocationManager : NSObject - -+ (id)sharedManager; - -- (BOOL) isAuthorizedStatusDetermined; -- (void) requestAlwaysAuthorization; - -- (void) startUpdatingLocation; -- (void) stopUpdatingLocation; - -- (void) setBackgroundStatus:(BOOL)isBackground; - -@end diff --git a/ios/app/MBLocationManager.m b/ios/app/MBLocationManager.m deleted file mode 100644 index 9aa235fc23..0000000000 --- a/ios/app/MBLocationManager.m +++ /dev/null @@ -1,142 +0,0 @@ -// -// MBLocationManager.m -// Hermes -// -// Dynamic Settings.bundle loading based on: -// http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the -// -// Created by Brad Leege on 3/8/15. -// Copyright (c) 2015 Mapbox. All rights reserved. -// - -#import "MBLocationManager.h" -#import "CoreLocation/CoreLocation.h" - -@interface MBLocationManager() - -@property (atomic) CLLocationManager *locationManager; -@property (atomic) BOOL isBackground; - -@end - -@implementation MBLocationManager - - -static MBLocationManager *sharedManager = nil; - -- (id) init { - if (self = [super init]) { - - NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; - if(!settingsBundle) { - NSLog(@"Could not find Settings.bundle"); - } else { - NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]]; - NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"]; - NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]]; - for(NSDictionary *prefSpecification in preferences) { - NSString *key = [prefSpecification objectForKey:@"Key"]; - if(key && [[prefSpecification allKeys] containsObject:@"DefaultValue"]) { - [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key]; - } - } - - [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister]; - } - - _locationManager = [[CLLocationManager alloc] init]; - _locationManager.distanceFilter = 2; - _locationManager.desiredAccuracy = kCLLocationAccuracyBest; - _locationManager.pausesLocationUpdatesAutomatically = YES; - [_locationManager setDelegate:self]; - } - return self; -} - -+ (id)sharedManager { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedManager = [[self alloc] init]; - }); - return sharedManager; -} - -- (BOOL) isAuthorizedStatusDetermined { - return ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined); -} - -- (void) requestAlwaysAuthorization { - if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { - [self.locationManager requestAlwaysAuthorization]; - } else { - // This is iOS 7 or below so Starting Location Updates will trigger authorization request - [self startUpdatingLocation]; - } -} - -- (void) setBackgroundStatus:(BOOL)isBackground { - self.isBackground = isBackground; -} - -- (void) startUpdatingLocation { - [self.locationManager startUpdatingLocation]; -} - -- (void) stopUpdatingLocation { - [self.locationManager stopUpdatingLocation]; -} - -#pragma mark CLLocationManagerDelegate -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { - CLLocation *loc = (CLLocation *)[locations objectAtIndex:0]; - NSLog(@"didUpdateLocations() called with %lu location in array. First Location = %f, %f", (unsigned long)locations.count, loc.coordinate.latitude, loc.coordinate.longitude); - -/** - if (![[NSUserDefaults standardUserDefaults] boolForKey:@"mapbox_metrics_enabled_preference"]) { - NSLog(@"Mapbox Metrics are not enabled, so return without sending in data."); - return; - } - - // Iterate through locations to pass all data - for (CLLocation *loc in locations) { - NSMutableDictionary *evt = [[NSMutableDictionary alloc] init]; - [evt setValue:[[NSNumber alloc] initWithDouble:loc.coordinate.latitude] forKey:@"lat"]; - [evt setValue:[[NSNumber alloc] initWithDouble:loc.coordinate.longitude] forKey:@"lng"]; - [evt setValue:[[NSNumber alloc] initWithBool:_isBackground] forKey:@"isBackground"]; - [[MapboxEvents sharedManager] pushEvent:@"location" withAttributes:evt]; - } -*/ -} - -- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { - NSString *newStatus = nil; - switch (status) { - case kCLAuthorizationStatusNotDetermined: - newStatus = @"User Hasn't Determined Yet"; - break; - case kCLAuthorizationStatusRestricted: - newStatus = @"Restricted and Can't Be Changed By User"; - break; - case kCLAuthorizationStatusDenied: - newStatus = @"User Explcitly Denied"; - [[MBLocationManager sharedManager] stopUpdatingLocation]; - break; - case kCLAuthorizationStatusAuthorized: - newStatus = @"User Has Authorized / Authorized Always"; - [[MBLocationManager sharedManager] startUpdatingLocation]; - break; - // case kCLAuthorizationStatusAuthorizedAlways: - // newStatus = @"Not Determined"; - // break; - case kCLAuthorizationStatusAuthorizedWhenInUse: - newStatus = @"User Has Authorized When In Use Only"; - [[MBLocationManager sharedManager] startUpdatingLocation]; - break; - default: - newStatus = @"Unknown"; - break; - } - NSLog(@"MBLocationManager didChangeAuthorizationStatus() called. New Status = %@", newStatus); -} - -@end diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 822549070d..98b337f927 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -5,7 +5,6 @@ #import #import -#import "MBLocationManager.h" static UIColor *const kTintColor = [UIColor colorWithRed:0.120 green:0.550 blue:0.670 alpha:1.000]; @@ -40,7 +39,6 @@ mbgl::Settings_NSUserDefaults *settings = nullptr; { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveState:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restoreState:) name:UIApplicationWillEnterForegroundNotification object:nil]; - [MBLocationManager sharedManager]; } return self; diff --git a/platform/ios/MBLocationManager.m b/platform/ios/MBLocationManager.m new file mode 100644 index 0000000000..9aa235fc23 --- /dev/null +++ b/platform/ios/MBLocationManager.m @@ -0,0 +1,142 @@ +// +// MBLocationManager.m +// Hermes +// +// Dynamic Settings.bundle loading based on: +// http://stackoverflow.com/questions/510216/can-you-make-the-settings-in-settings-bundle-default-even-if-you-dont-open-the +// +// Created by Brad Leege on 3/8/15. +// Copyright (c) 2015 Mapbox. All rights reserved. +// + +#import "MBLocationManager.h" +#import "CoreLocation/CoreLocation.h" + +@interface MBLocationManager() + +@property (atomic) CLLocationManager *locationManager; +@property (atomic) BOOL isBackground; + +@end + +@implementation MBLocationManager + + +static MBLocationManager *sharedManager = nil; + +- (id) init { + if (self = [super init]) { + + NSString *settingsBundle = [[NSBundle mainBundle] pathForResource:@"Settings" ofType:@"bundle"]; + if(!settingsBundle) { + NSLog(@"Could not find Settings.bundle"); + } else { + NSDictionary *settings = [NSDictionary dictionaryWithContentsOfFile:[settingsBundle stringByAppendingPathComponent:@"Root.plist"]]; + NSArray *preferences = [settings objectForKey:@"PreferenceSpecifiers"]; + NSMutableDictionary *defaultsToRegister = [[NSMutableDictionary alloc] initWithCapacity:[preferences count]]; + for(NSDictionary *prefSpecification in preferences) { + NSString *key = [prefSpecification objectForKey:@"Key"]; + if(key && [[prefSpecification allKeys] containsObject:@"DefaultValue"]) { + [defaultsToRegister setObject:[prefSpecification objectForKey:@"DefaultValue"] forKey:key]; + } + } + + [[NSUserDefaults standardUserDefaults] registerDefaults:defaultsToRegister]; + } + + _locationManager = [[CLLocationManager alloc] init]; + _locationManager.distanceFilter = 2; + _locationManager.desiredAccuracy = kCLLocationAccuracyBest; + _locationManager.pausesLocationUpdatesAutomatically = YES; + [_locationManager setDelegate:self]; + } + return self; +} + ++ (id)sharedManager { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedManager = [[self alloc] init]; + }); + return sharedManager; +} + +- (BOOL) isAuthorizedStatusDetermined { + return ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined); +} + +- (void) requestAlwaysAuthorization { + if ([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) { + [self.locationManager requestAlwaysAuthorization]; + } else { + // This is iOS 7 or below so Starting Location Updates will trigger authorization request + [self startUpdatingLocation]; + } +} + +- (void) setBackgroundStatus:(BOOL)isBackground { + self.isBackground = isBackground; +} + +- (void) startUpdatingLocation { + [self.locationManager startUpdatingLocation]; +} + +- (void) stopUpdatingLocation { + [self.locationManager stopUpdatingLocation]; +} + +#pragma mark CLLocationManagerDelegate +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { + CLLocation *loc = (CLLocation *)[locations objectAtIndex:0]; + NSLog(@"didUpdateLocations() called with %lu location in array. First Location = %f, %f", (unsigned long)locations.count, loc.coordinate.latitude, loc.coordinate.longitude); + +/** + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"mapbox_metrics_enabled_preference"]) { + NSLog(@"Mapbox Metrics are not enabled, so return without sending in data."); + return; + } + + // Iterate through locations to pass all data + for (CLLocation *loc in locations) { + NSMutableDictionary *evt = [[NSMutableDictionary alloc] init]; + [evt setValue:[[NSNumber alloc] initWithDouble:loc.coordinate.latitude] forKey:@"lat"]; + [evt setValue:[[NSNumber alloc] initWithDouble:loc.coordinate.longitude] forKey:@"lng"]; + [evt setValue:[[NSNumber alloc] initWithBool:_isBackground] forKey:@"isBackground"]; + [[MapboxEvents sharedManager] pushEvent:@"location" withAttributes:evt]; + } +*/ +} + +- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { + NSString *newStatus = nil; + switch (status) { + case kCLAuthorizationStatusNotDetermined: + newStatus = @"User Hasn't Determined Yet"; + break; + case kCLAuthorizationStatusRestricted: + newStatus = @"Restricted and Can't Be Changed By User"; + break; + case kCLAuthorizationStatusDenied: + newStatus = @"User Explcitly Denied"; + [[MBLocationManager sharedManager] stopUpdatingLocation]; + break; + case kCLAuthorizationStatusAuthorized: + newStatus = @"User Has Authorized / Authorized Always"; + [[MBLocationManager sharedManager] startUpdatingLocation]; + break; + // case kCLAuthorizationStatusAuthorizedAlways: + // newStatus = @"Not Determined"; + // break; + case kCLAuthorizationStatusAuthorizedWhenInUse: + newStatus = @"User Has Authorized When In Use Only"; + [[MBLocationManager sharedManager] startUpdatingLocation]; + break; + default: + newStatus = @"Unknown"; + break; + } + NSLog(@"MBLocationManager didChangeAuthorizationStatus() called. New Status = %@", newStatus); +} + +@end diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index 281755a4c8..0592683d66 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -21,6 +21,8 @@ #import "NSArray+MGLAdditions.h" #import "NSDictionary+MGLAdditions.h" +#import "MBLocationManager.h" + // Returns the path to the default cache database on this system. const std::string &defaultCacheDatabase() { @@ -338,6 +340,9 @@ mbgl::DefaultFileSource *mbglFileSource = nullptr; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillForeground:) name:UIApplicationWillEnterForegroundNotification object:nil]; + // Setup MBLocationManager for metrics + [MBLocationManager sharedManager]; + // set initial position // mbglMap->setLatLngZoom(mbgl::LatLng(0, 0), mbglMap->getMinZoom()); diff --git a/styles b/styles index c130393379..25b1b7dff3 160000 --- a/styles +++ b/styles @@ -1 +1 @@ -Subproject commit c1303933798e1bb48649d8a64b71038b4d3ed0a4 +Subproject commit 25b1b7dff37a18151e3286144bc8013b432a8860 -- cgit v1.2.1