summaryrefslogtreecommitdiff
path: root/ios/app/MBXViewController.mm
diff options
context:
space:
mode:
Diffstat (limited to 'ios/app/MBXViewController.mm')
-rw-r--r--ios/app/MBXViewController.mm266
1 files changed, 266 insertions, 0 deletions
diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm
new file mode 100644
index 0000000000..4945b73cc5
--- /dev/null
+++ b/ios/app/MBXViewController.mm
@@ -0,0 +1,266 @@
+#import "MBXViewController.h"
+
+#import <mbgl/ios/MGLMapView.h>
+
+#import <mbgl/platform/darwin/settings_nsuserdefaults.hpp>
+
+#import <CoreLocation/CoreLocation.h>
+
+static UIColor *const kTintColor = [UIColor colorWithRed:0.120 green:0.550 blue:0.670 alpha:1.000];
+
+static NSDictionary *const kStyles = @{
+ @"bright-v6": @"Bright",
+ @"basic-v6": @"Basic",
+ @"outdoors-v6": @"Outdoors",
+ @"satellite-v6": @"Satellite"
+};
+
+@interface MBXViewController () <UIActionSheetDelegate, CLLocationManagerDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) CLLocationManager *locationManager;
+
+@end
+
+@implementation MBXViewController
+
+mbgl::Settings_NSUserDefaults *settings = nullptr;
+
+#pragma mark - Setup
+
+- (id)init
+{
+ self = [super init];
+
+ if (self)
+ {
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveState:) name:UIApplicationDidEnterBackgroundNotification object:nil];
+ [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(restoreState:) name:UIApplicationWillEnterForegroundNotification object:nil];
+ }
+
+ return self;
+}
+
+- (void)viewDidLoad
+{
+ [super viewDidLoad];
+
+ NSString *accessToken = [[NSProcessInfo processInfo] environment][@"MAPBOX_ACCESS_TOKEN"];
+ if (accessToken) {
+ // Store to preferences so that we can launch the app later on without having to specify
+ // token.
+ [[NSUserDefaults standardUserDefaults] setObject:accessToken forKey:@"access_token"];
+ } else {
+ // Try to retrieve from preferences, maybe we've stored them there previously and can reuse
+ // the token.
+ accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:@"access_token"];
+ }
+
+ if ( ! accessToken) NSLog(@"No access token set. Mapbox vector tiles won't work.");
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds accessToken:accessToken];
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ [self.view addSubview:self.mapView];
+
+ self.mapView.viewControllerForLayoutGuides = self;
+
+ self.view.tintColor = kTintColor;
+ self.navigationController.navigationBar.tintColor = kTintColor;
+ self.mapView.tintColor = kTintColor;
+
+ self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"settings.png"]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(showSettings)];
+
+ UIButton *titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
+ [titleButton setFrame:CGRectMake(0, 0, 120, 40)];
+ [titleButton setTitle:[[kStyles allValues] firstObject] forState:UIControlStateNormal];
+ [titleButton setTitleColor:kTintColor forState:UIControlStateNormal];
+ [titleButton addTarget:self action:@selector(cycleStyles) forControlEvents:UIControlEventTouchUpInside];
+ self.navigationItem.titleView = titleButton;
+
+ self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"locateUser.png"]
+ style:UIBarButtonItemStylePlain
+ target:self
+ action:@selector(locateUser)];
+
+ settings = new mbgl::Settings_NSUserDefaults();
+ [self restoreState:nil];
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+- (void)saveState:(NSNotification *)notification
+{
+ if (self.mapView && settings)
+ {
+ settings->longitude = self.mapView.centerCoordinate.longitude;
+ settings->latitude = self.mapView.centerCoordinate.latitude;
+ settings->zoom = self.mapView.zoomLevel;
+ settings->bearing = self.mapView.direction;
+ settings->debug = self.mapView.isDebugActive;
+ settings->save();
+ }
+}
+
+- (void)restoreState:(NSNotification *)notification
+{
+ if (self.mapView && settings) {
+ settings->load();
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(settings->latitude, settings->longitude) zoomLevel:settings->zoom animated:NO];
+ self.mapView.direction = settings->bearing;
+ [self.mapView setDebugActive:settings->debug];
+ }
+}
+
+#pragma clang diagnostic pop
+
+- (NSUInteger)supportedInterfaceOrientations
+{
+ return UIInterfaceOrientationMaskAll;
+}
+
+#pragma mark - Actions
+
+- (void)showSettings
+{
+ UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:@"Map Settings"
+ delegate:self
+ cancelButtonTitle:@"Cancel"
+ destructiveButtonTitle:nil
+ otherButtonTitles:@"Reset North", @"Reset Position", @"Toggle Debug", nil];
+
+ [sheet showFromBarButtonItem:self.navigationItem.leftBarButtonItem animated:YES];
+}
+
+- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
+{
+ if (buttonIndex == actionSheet.firstOtherButtonIndex)
+ {
+ [self.mapView resetNorth];
+ }
+ else if (buttonIndex == actionSheet.firstOtherButtonIndex + 1)
+ {
+ [self.mapView resetPosition];
+ }
+ else if (buttonIndex == actionSheet.firstOtherButtonIndex + 2)
+ {
+ [self.mapView toggleDebug];
+ }
+}
+
+- (void)cycleStyles
+{
+ UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
+
+ NSString *styleName = [titleButton titleForState:UIControlStateNormal];
+
+ if ( ! styleName)
+ {
+ styleName = [[kStyles allKeys] firstObject];
+ }
+ else
+ {
+ NSUInteger index = [[kStyles allValues] indexOfObject:styleName] + 1;
+ if (index == [[kStyles allKeys] count]) index = 0;
+ styleName = [[kStyles allKeys] objectAtIndex:index];
+ }
+
+ [self.mapView useBundledStyleNamed:styleName];
+
+ [titleButton setTitle:kStyles[styleName] forState:UIControlStateNormal];
+}
+
+- (void)locateUser
+{
+ if ( ! self.locationManager)
+ {
+ self.locationManager = [CLLocationManager new];
+ self.locationManager.delegate = self;
+ }
+
+ if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied)
+ {
+ [[[UIAlertView alloc] initWithTitle:@"Authorization Denied"
+ message:@"Please enable location services for this app in Privacy settings."
+ delegate:nil
+ cancelButtonTitle:nil otherButtonTitles:@"OK", nil] show];
+ }
+ else
+ {
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)])
+ {
+ if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse)
+ {
+ [self.locationManager startUpdatingLocation];
+ }
+ else
+ {
+ [_locationManager requestWhenInUseAuthorization];
+ }
+ }
+ else
+ {
+ [self.locationManager startUpdatingLocation];
+ }
+#else
+ [self.locationManager startUpdatingLocation];
+#endif
+ }
+}
+
+#pragma mark - Destruction
+
+- (void)dealloc
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+
+ if (settings)
+ {
+ [self saveState:nil];
+ delete settings;
+ settings = nullptr;
+ }
+}
+
+#pragma mark - Location
+
+- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
+{
+ switch (status)
+ {
+ case kCLAuthorizationStatusAuthorizedAlways:
+#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
+ case kCLAuthorizationStatusAuthorizedWhenInUse:
+#endif
+ {
+ [manager startUpdatingLocation];
+ break;
+ }
+ default:
+ {
+ }
+ }
+}
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
+{
+ CLLocation *latestLocation = locations.lastObject;
+
+ if ([latestLocation distanceFromLocation:[[CLLocation alloc] initWithLatitude:self.mapView.centerCoordinate.latitude longitude:self.mapView.centerCoordinate.longitude]] > 100)
+ {
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(latestLocation.coordinate.latitude, latestLocation.coordinate.longitude) zoomLevel:17 animated:YES];
+ }
+
+ [self.locationManager stopUpdatingLocation];
+}
+
+#pragma clang diagnostic pop
+
+@end