diff --git a/gyp/platform-ios.gypi b/gyp/platform-ios.gypi index d23192c8c6d..1f96f94702e 100644 --- a/gyp/platform-ios.gypi +++ b/gyp/platform-ios.gypi @@ -25,6 +25,8 @@ '../platform/ios/MGLMapView.mm', '../platform/ios/MGLFileCache.h', '../platform/ios/MGLFileCache.mm', + '../include/mbgl/ios/MGLAccountManager.h', + '../platform/ios/MGLAccountManager.m', '../include/mbgl/ios/MGLAnnotation.h', '../include/mbgl/ios/MGLUserLocation.h', '../platform/ios/MGLUserLocation_Private.h', diff --git a/include/mbgl/ios/MGLAccountManager.h b/include/mbgl/ios/MGLAccountManager.h new file mode 100644 index 00000000000..c1b7406b9ea --- /dev/null +++ b/include/mbgl/ios/MGLAccountManager.h @@ -0,0 +1,6 @@ +@interface MGLAccountManager : NSObject + ++ (void) setAccessToken:(NSString *) accessToken; ++ (NSString *) accessToken; + +@end \ No newline at end of file diff --git a/include/mbgl/ios/MGLMapView.h b/include/mbgl/ios/MGLMapView.h index 88d75088bf8..cf1eeb8a7dc 100644 --- a/include/mbgl/ios/MGLMapView.h +++ b/include/mbgl/ios/MGLMapView.h @@ -20,6 +20,11 @@ IB_DESIGNABLE /** @name Initializing a Map View */ +/** Initialize a map view with the default style, given frame, and access token set in MapboxGL singleton. +* @param frame The frame with which to initialize the map view. +* @return An initialized map view, or `nil` if the map view was unable to be initialized. */ +- (instancetype)initWithFrame:(CGRect)frame; + /** Initialize a map view with the default style and a given frame and access token. * @param frame The frame with which to initialize the map view. * @param accessToken A Mapbox API access token. @@ -33,8 +38,6 @@ IB_DESIGNABLE * @return An initialized map view, or `nil` if the map view was unable to be initialized. */ - (instancetype)initWithFrame:(CGRect)frame accessToken:(NSString *)accessToken styleURL:(NSURL *)styleURL; -- (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("Instantiating an MGLMapView requires setting a style and/or an access token."))); - #pragma mark - Authorizing Access /** @name Authorizing Access */ diff --git a/include/mbgl/ios/MapboxGL.h b/include/mbgl/ios/MapboxGL.h index c32915bc76b..34e080a5112 100644 --- a/include/mbgl/ios/MapboxGL.h +++ b/include/mbgl/ios/MapboxGL.h @@ -2,3 +2,4 @@ #import "MGLMapView.h" #import "MGLTypes.h" #import "MGLUserLocation.h" +#import "MGLAccountManager.h" \ No newline at end of file diff --git a/ios/app/MBXAppDelegate.m b/ios/app/MBXAppDelegate.m index f2ef69ec634..90c552aba03 100644 --- a/ios/app/MBXAppDelegate.m +++ b/ios/app/MBXAppDelegate.m @@ -1,11 +1,29 @@ #import "MBXAppDelegate.h" #import "MBXViewController.h" +#import +#import #import @implementation MBXAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Set Access Token + 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."); + + // Start Mapbox GL SDK + [MGLAccountManager setAccessToken:accessToken]; + self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[MBXViewController new]]; [self.window makeKeyAndVisible]; diff --git a/ios/app/MBXViewController.mm b/ios/app/MBXViewController.mm index 98c8e016dbe..eb77a2ec800 100644 --- a/ios/app/MBXViewController.mm +++ b/ios/app/MBXViewController.mm @@ -52,20 +52,7 @@ - (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 = [[MGLMapView alloc] initWithFrame:self.view.bounds]; self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; self.mapView.showsUserLocation = YES; self.mapView.delegate = self; diff --git a/platform/ios/MGLAccountManager.m b/platform/ios/MGLAccountManager.m new file mode 100644 index 00000000000..b1a80fd6a75 --- /dev/null +++ b/platform/ios/MGLAccountManager.m @@ -0,0 +1,53 @@ +#import + +#import "MGLAccountManager.h" +#import "NSProcessInfo+MGLAdditions.h" +#import "MGLMapboxEvents.h" + +@interface MGLAccountManager() + +@property (atomic) NSString *accessToken; + +@end + + +@implementation MGLAccountManager + +static MGLAccountManager *_sharedManager; + +// Can be called from any thread. +// ++ (instancetype) sharedInstance { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + if ( ! NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { + void (^setupBlock)() = ^{ + _sharedManager = [[self alloc] init]; + }; + if ( ! [[NSThread currentThread] isMainThread]) { + dispatch_sync(dispatch_get_main_queue(), ^{ + setupBlock(); + }); + } + else { + setupBlock(); + } + } + }); + return _sharedManager; +} + ++ (void) setAccessToken:(NSString *) accessToken { + [[MGLAccountManager sharedInstance] setAccessToken:accessToken]; + + // Update MGLMapboxEvents + // NOTE: This is (likely) the initial setup of MGLMapboxEvents + [MGLMapboxEvents setToken:accessToken]; +} + ++ (NSString *) accessToken { + return [MGLAccountManager sharedInstance].accessToken; +} + + +@end \ No newline at end of file diff --git a/platform/ios/MGLMapView.mm b/platform/ios/MGLMapView.mm index fd448b89921..01ef0835ea7 100644 --- a/platform/ios/MGLMapView.mm +++ b/platform/ios/MGLMapView.mm @@ -28,6 +28,7 @@ #import "SMCalloutView.h" #import "MGLMapboxEvents.h" +#import "MapboxGL.h" #import @@ -109,6 +110,7 @@ - (instancetype)initWithFrame:(CGRect)frame if (self && [self commonInit]) { self.styleURL = nil; + self.accessToken = [MGLAccountManager accessToken]; return self; }