diff --git a/ios/app/MBLocationManager.h b/ios/app/MBLocationManager.h new file mode 100644 index 000000000..84a847c9e --- /dev/null +++ b/ios/app/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.m b/ios/app/MBLocationManager.m new file mode 100644 index 000000000..9aa235fc2 --- /dev/null +++ b/ios/app/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