[osx] Fixed URL handler, reload for new access token

This commit is contained in:
Minh Nguyễn
2015-12-24 23:27:36 -08:00
committed by Minh Nguyễn
parent 019b3d5b92
commit 44a4f7bca2
3 changed files with 85 additions and 66 deletions

View File

@@ -1,8 +1,14 @@
#import <Cocoa/Cocoa.h>
extern NSString * const MGLMapboxAccessTokenDefaultsKey;
@class MapDocument;
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (weak) IBOutlet NSWindow *preferencesWindow;
@property (copy) NSURL *pendingURL;
@end

View File

@@ -4,7 +4,7 @@
#import <Mapbox/Mapbox.h>
static NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken";
NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken";
@interface AppDelegate ()
@@ -32,11 +32,6 @@ static NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
[[NSAppleEventManager sharedAppleEventManager] setEventHandler:self
andSelector:@selector(handleGetURLEvent:withReplyEvent:)
forEventClass:kInternetEventClass
@@ -55,56 +50,11 @@ static NSString * const MGLMapboxAccessTokenDefaultsKey = @"MGLMapboxAccessToken
}
}
- (void)applicationWillTerminate:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)userDefaultsDidChange:(NSNotification *)notification {
NSUserDefaults *userDefaults = notification.object;
NSString *accessToken = [userDefaults stringForKey:MGLMapboxAccessTokenDefaultsKey];
if (![accessToken isEqualToString:[MGLAccountManager accessToken]]) {
[MGLAccountManager setAccessToken:accessToken];
[self.mainDocument reload:self];
}
}
- (MapDocument *)mainDocument {
NSDocument *mainDocument = NSApp.mainWindow.windowController.document;
return [mainDocument isKindOfClass:[MapDocument class]] ? (MapDocument *)mainDocument : nil;
}
#pragma mark Services
- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
[[NSDocumentController sharedDocumentController] newDocument:self];
NSURL *url = [NSURL URLWithString:[event paramDescriptorForKeyword:keyDirectObject].stringValue];
NS_MUTABLE_DICTIONARY_OF(NSString *, NSString *) *params = [[NSMutableDictionary alloc] init];
for (NSString *param in [url.query componentsSeparatedByString:@"&"]) {
NSArray *parts = [param componentsSeparatedByString:@"="];
if (parts.count >= 2) {
params[parts[0]] = [parts[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
}
NSString *centerString = params[@"center"];
if (centerString) {
NSArray *coordinateValues = [centerString componentsSeparatedByString:@","];
if (coordinateValues.count == 2) {
self.mainDocument.mapView.centerCoordinate = CLLocationCoordinate2DMake([coordinateValues[0] doubleValue],
[coordinateValues[1] doubleValue]);
}
}
NSString *zoomLevelString = params[@"zoom"];
if (zoomLevelString.length) {
self.mainDocument.mapView.zoomLevel = zoomLevelString.doubleValue;
}
NSString *directionString = params[@"bearing"];
if (directionString.length) {
self.mainDocument.mapView.direction = directionString.doubleValue;
}
self.pendingURL = [NSURL URLWithString:[event paramDescriptorForKeyword:keyDirectObject].stringValue];
[[NSDocumentController sharedDocumentController] openUntitledDocumentAndDisplay:YES error:NULL];
}
#pragma mark Help methods

View File

@@ -1,5 +1,6 @@
#import "MapDocument.h"
#import "AppDelegate.h"
#import "DroppedPinAnnotation.h"
#import "NSValue+Additions.h"
@@ -40,16 +41,25 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
return @"MapDocument";
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)windowControllerWillLoadNib:(NSWindowController *)windowController {
NSDocument *sourceDocument = [[NSDocumentController sharedDocumentController] documentForWindow:NSApp.mainWindow];
if ([sourceDocument isKindOfClass:[MapDocument class]]) {
_inheritedStyleURL = [(MapDocument *)sourceDocument mapView].styleURL;
NSDocument *currentDocument = [NSDocumentController sharedDocumentController].currentDocument;
if ([currentDocument isKindOfClass:[MapDocument class]]) {
_inheritedStyleURL = [(MapDocument *)currentDocument mapView].styleURL;
}
}
- (void)windowControllerDidLoadNib:(NSWindowController *)controller {
[super windowControllerDidLoadNib:controller];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(userDefaultsDidChange:)
name:NSUserDefaultsDidChangeNotification
object:nil];
_spellOutNumberFormatter = [[NSNumberFormatter alloc] init];
NSPressGestureRecognizer *pressGestureRecognizer = [[NSPressGestureRecognizer alloc] initWithTarget:self action:@selector(handlePressGesture:)];
@@ -58,6 +68,9 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
if (_inheritedStyleURL) {
self.mapView.styleURL = _inheritedStyleURL;
}
AppDelegate *appDelegate = (AppDelegate *)NSApp.delegate;
[self populateFromURL:appDelegate.pendingURL];
appDelegate.pendingURL = nil;
}
- (NSString *)displayName {
@@ -71,6 +84,25 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
return self.windowControllers.firstObject.window;
}
- (void)userDefaultsDidChange:(NSNotification *)notification {
NSUserDefaults *userDefaults = notification.object;
NSString *accessToken = [userDefaults stringForKey:MGLMapboxAccessTokenDefaultsKey];
if (![accessToken isEqualToString:[MGLAccountManager accessToken]]) {
[MGLAccountManager setAccessToken:accessToken];
[self reload:self];
}
}
#pragma mark NSWindowDelegate methods
- (void)window:(NSWindow *)window willEncodeRestorableState:(NSCoder *)state {
[state encodeObject:self.mapView.styleURL forKey:@"MBXMapViewStyleURL"];
}
- (void)window:(NSWindow *)window didDecodeRestorableState:(NSCoder *)state {
self.mapView.styleURL = [state decodeObjectForKey:@"MBXMapViewStyleURL"];
}
#pragma mark Services
- (IBAction)showShareMenu:(id)sender {
@@ -88,6 +120,47 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
self.mapView.zoomLevel, centerCoordinate.latitude, centerCoordinate.longitude, self.mapView.direction]];
}
- (void)populateFromURL:(NSURL *)url {
if (![url.scheme isEqualToString:@"mapboxgl"]) {
return;
}
// mapboxgl://?center=29.95,-90.066667&zoom=14&bearing=45&pitch=30
NS_MUTABLE_DICTIONARY_OF(NSString *, NSString *) *params = [[NSMutableDictionary alloc] init];
for (NSString *param in [url.query componentsSeparatedByString:@"&"]) {
NSArray *parts = [param componentsSeparatedByString:@"="];
if (parts.count >= 2) {
params[parts[0]] = [parts[1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
}
}
NSString *zoomLevelString = params[@"zoom"];
if (zoomLevelString.length) {
_mapView.zoomLevel = zoomLevelString.doubleValue;
}
NSString *directionString = params[@"bearing"];
if (directionString.length) {
_mapView.direction = directionString.doubleValue;
}
NSString *centerString = params[@"center"];
if (centerString) {
NSArray *coordinateValues = [centerString componentsSeparatedByString:@","];
if (coordinateValues.count == 2) {
_mapView.centerCoordinate = CLLocationCoordinate2DMake([coordinateValues[0] doubleValue],
[coordinateValues[1] doubleValue]);
}
}
NSString *pitchString = params[@"pitch"];
if (pitchString.length) {
MGLMapCamera *camera = _mapView.camera;
camera.pitch = pitchString.doubleValue;
_mapView.camera = camera;
}
}
#pragma mark View methods
- (IBAction)setStyle:(id)sender {
@@ -464,16 +537,6 @@ static const CLLocationCoordinate2D WorldTourDestinations[] = {
return NO;
}
#pragma mark NSWindowDelegate methods
- (void)window:(NSWindow *)window willEncodeRestorableState:(NSCoder *)state {
[state encodeObject:self.mapView.styleURL forKey:@"MBXMapViewStyleURL"];
}
- (void)window:(NSWindow *)window didDecodeRestorableState:(NSCoder *)state {
self.mapView.styleURL = [state decodeObjectForKey:@"MBXMapViewStyleURL"];
}
#pragma mark NSSharingServicePickerDelegate methods
- (NS_ARRAY_OF(NSSharingService *) *)sharingServicePicker:(NSSharingServicePicker *)sharingServicePicker sharingServicesForItems:(NSArray *)items proposedSharingServices:(NS_ARRAY_OF(NSSharingService *) *)proposedServices {