diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2016-03-05 18:00:11 -0800 |
---|---|---|
committer | Minh Nguyễn <mxn@1ec5.org> | 2016-03-10 17:08:58 -0800 |
commit | e36218a8668316e8c1b0bcc06d43dad31461615c (patch) | |
tree | 04d5e58ae0c4dea4b0a50e034a8a630564cb7a53 /platform/darwin | |
parent | 081ee9fbefbdb37f116a5bf2c0383586bce6608a (diff) | |
download | qtlocation-mapboxgl-e36218a8668316e8c1b0bcc06d43dad31461615c.tar.gz |
[osx] Added OS X support for offline downloads
Diffstat (limited to 'platform/darwin')
-rw-r--r-- | platform/darwin/include/MGLAccountManager.h | 49 | ||||
-rw-r--r-- | platform/darwin/src/MGLAccountManager.m | 123 | ||||
-rw-r--r-- | platform/darwin/src/MGLAccountManager_Private.h | 11 | ||||
-rw-r--r-- | platform/darwin/src/MGLDownloadController.mm | 20 | ||||
-rw-r--r-- | platform/darwin/src/MGLTilePyramidDownloadRegion.mm | 4 | ||||
-rw-r--r-- | platform/darwin/src/NSBundle+MGLAdditions.h | 24 | ||||
-rw-r--r-- | platform/darwin/src/NSBundle+MGLAdditions.m | 40 | ||||
-rw-r--r-- | platform/darwin/src/NSProcessInfo+MGLAdditions.h | 13 | ||||
-rw-r--r-- | platform/darwin/src/NSProcessInfo+MGLAdditions.m | 17 |
9 files changed, 299 insertions, 2 deletions
diff --git a/platform/darwin/include/MGLAccountManager.h b/platform/darwin/include/MGLAccountManager.h new file mode 100644 index 0000000000..5cf729ef3a --- /dev/null +++ b/platform/darwin/include/MGLAccountManager.h @@ -0,0 +1,49 @@ +#import <Foundation/Foundation.h> + +#import "MGLTypes.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + The MGLAccountManager object provides a global way to set a Mapbox API access + token, as well as other settings used framework-wide. + */ +@interface MGLAccountManager : NSObject + +#pragma mark Authorizing Access + +/** + Set the [Mapbox access token](https://www.mapbox.com/help/define-access-token/) + to be used by all instances of MGLMapView in the current application. + + Mapbox-hosted vector tiles and styles require an API access token, which you + can obtain from the + [Mapbox account page](https://www.mapbox.com/studio/account/tokens/). Access + tokens associate requests to Mapbox’s vector tile and style APIs with your + Mapbox account. They also deter other developers from using your styles without + your permission. + + @param accessToken A Mapbox access token. Calling this method with a value of + `nil` has no effect. + + @note You must set the access token before attempting to load any Mapbox-hosted + style. Therefore, you should generally set it before creating an instance of + MGLMapView. The recommended way to set an access token is to add an entry to + your application’s Info.plist file with the key `MGLMapboxAccessToken` and + the type String. Alternatively, you may call this method from your + application delegate’s `-applicationDidFinishLaunching:` method. + */ ++ (void)setAccessToken:(nullable NSString *)accessToken; + +/** + Returns the + [Mapbox access token](https://www.mapbox.com/help/define-access-token/) in use + by instances of MGLMapView in the current application. + */ ++ (nullable NSString *)accessToken; + ++ (BOOL)mapboxMetricsEnabledSettingShownInApp __attribute__((deprecated("Telemetry settings are now always shown in the ℹ️ menu."))); + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLAccountManager.m b/platform/darwin/src/MGLAccountManager.m new file mode 100644 index 0000000000..bfaf9faae9 --- /dev/null +++ b/platform/darwin/src/MGLAccountManager.m @@ -0,0 +1,123 @@ +#import "MGLAccountManager_Private.h" +#import "MGLMapView.h" +#import "NSBundle+MGLAdditions.h" +#import "NSProcessInfo+MGLAdditions.h" +#import "NSString+MGLAdditions.h" + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR +#import "MGLMapboxEvents.h" + +#import "FABKitProtocol.h" +#import "Fabric+FABKits.h" + +@interface MGLAccountManager () <FABKit> + +@property (atomic) NSString *accessToken; + +@end +#else +@interface MGLAccountManager () + +@property (atomic) NSString *accessToken; + +@end +#endif + +@implementation MGLAccountManager + +#pragma mark - Internal + ++ (void)load { + // Read the initial configuration from Info.plist. + NSString *accessToken = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"MGLMapboxAccessToken"]; + if (accessToken.length) { + self.accessToken = accessToken; + } +} + ++ (instancetype)sharedManager { + if (NSProcessInfo.processInfo.mgl_isInterfaceBuilderDesignablesAgent) { + return nil; + } + static dispatch_once_t onceToken; + static MGLAccountManager *_sharedManager; + void (^setupBlock)() = ^{ + dispatch_once(&onceToken, ^{ + _sharedManager = [[self alloc] init]; + }); + }; + if (![[NSThread currentThread] isMainThread]) { + dispatch_sync(dispatch_get_main_queue(), ^{ + setupBlock(); + }); + } else { + setupBlock(); + } + return _sharedManager; +} + ++ (BOOL)mapboxMetricsEnabledSettingShownInApp { + NSLog(@"mapboxMetricsEnabledSettingShownInApp is no longer necessary; the Mapbox iOS SDK has changed to always provide a telemetry setting in-app."); + return YES; +} + ++ (void)setAccessToken:(NSString *)accessToken { + accessToken = [accessToken stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceAndNewlineCharacterSet]]; + if (!accessToken.length) { + return; + } + + [MGLAccountManager sharedManager].accessToken = accessToken; + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + // Update MGLMapboxEvents + // NOTE: This is (likely) the initial setup of MGLMapboxEvents + [MGLMapboxEvents sharedManager]; +#endif +} + ++ (NSString *)accessToken { + return [MGLAccountManager sharedManager].accessToken; +} + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + +#pragma mark - Fabric + ++ (NSString *)bundleIdentifier { + return [NSBundle mgl_frameworkBundleIdentifier]; +} + ++ (NSString *)kitDisplayVersion { + return [NSBundle mgl_frameworkInfoDictionary][@"CFBundleShortVersionString"]; +} + ++ (void)initializeIfNeeded { + Class fabric = NSClassFromString(@"Fabric"); + + if (fabric) { + NSDictionary *configuration = [fabric configurationDictionaryForKitClass:[MGLAccountManager class]]; + if (!configuration || !configuration[@"accessToken"]) { + NSLog(@"Configuration dictionary returned by Fabric was nil or doesn’t have accessToken. Can’t initialize MGLAccountManager."); + return; + } + [self setAccessToken:configuration[@"accessToken"]]; + MGLAccountManager *sharedAccountManager = [self sharedManager]; + NSLog(@"MGLAccountManager was initialized with access token: %@", sharedAccountManager.accessToken); + } else { + NSLog(@"MGLAccountManager is used in a project that doesn’t have Fabric."); + } + + // https://github.com/mapbox/mapbox-gl-native/issues/2966 + mgl_linkBundleCategory(); + mgl_linkStringCategory(); + mgl_linkProcessInfoCategory(); + + // https://github.com/mapbox/mapbox-gl-native/issues/3113 + [MGLMapView class]; +} + +#endif + +@end diff --git a/platform/darwin/src/MGLAccountManager_Private.h b/platform/darwin/src/MGLAccountManager_Private.h new file mode 100644 index 0000000000..655af08f20 --- /dev/null +++ b/platform/darwin/src/MGLAccountManager_Private.h @@ -0,0 +1,11 @@ +#import "MGLAccountManager.h" + +@interface MGLAccountManager (Private) + +/// Returns the shared instance of the `MGLAccountManager` class. ++ (instancetype)sharedManager; + +/// The current global access token. +@property (atomic) NSString *accessToken; + +@end diff --git a/platform/darwin/src/MGLDownloadController.mm b/platform/darwin/src/MGLDownloadController.mm index e4dd273032..95eae86b53 100644 --- a/platform/darwin/src/MGLDownloadController.mm +++ b/platform/darwin/src/MGLDownloadController.mm @@ -29,9 +29,25 @@ - (instancetype)initWithFileName:(NSString *)fileName { if (self = [super init]) { +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *fileCachePath = [paths.firstObject stringByAppendingPathComponent:fileName]; - _mbglFileSource = new mbgl::DefaultFileSource(fileCachePath.UTF8String, [NSBundle mainBundle].resourceURL.path.UTF8String); + NSString *cachePath = [paths.firstObject stringByAppendingPathComponent:fileName]; +#elif TARGET_OS_MAC + NSURL *cacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory + inDomain:NSUserDomainMask + appropriateForURL:nil + create:YES + error:nil]; + cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent: + [NSBundle mainBundle].bundleIdentifier]; + [[NSFileManager defaultManager] createDirectoryAtURL:cacheDirectoryURL + withIntermediateDirectories:YES + attributes:nil + error:nil]; + NSURL *cacheURL = [cacheDirectoryURL URLByAppendingPathComponent:fileName]; + NSString *cachePath = cacheURL ? cacheURL.path : @""; +#endif + _mbglFileSource = new mbgl::DefaultFileSource(cachePath.UTF8String, [NSBundle mainBundle].resourceURL.path.UTF8String); // Observe for changes to the global access token (and find out the current one). [[MGLAccountManager sharedManager] addObserver:self diff --git a/platform/darwin/src/MGLTilePyramidDownloadRegion.mm b/platform/darwin/src/MGLTilePyramidDownloadRegion.mm index 942450c0c2..94c0ac6358 100644 --- a/platform/darwin/src/MGLTilePyramidDownloadRegion.mm +++ b/platform/darwin/src/MGLTilePyramidDownloadRegion.mm @@ -1,5 +1,9 @@ #import "MGLTilePyramidDownloadRegion.h" +#if !TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR + #import <Cocoa/Cocoa.h> +#endif + #import "MGLDownloadRegion_Private.h" #import "MGLGeometry_Private.h" #import "MGLStyle.h" diff --git a/platform/darwin/src/NSBundle+MGLAdditions.h b/platform/darwin/src/NSBundle+MGLAdditions.h new file mode 100644 index 0000000000..52ef7fbfa7 --- /dev/null +++ b/platform/darwin/src/NSBundle+MGLAdditions.h @@ -0,0 +1,24 @@ +#import <Foundation/Foundation.h> + +#import "MGLTypes.h" + +NS_ASSUME_NONNULL_BEGIN + +void mgl_linkBundleCategory(); + +@interface NSBundle (MGLAdditions) + +/// Returns the bundle containing the SDK’s classes and Info.plist file. ++ (instancetype)mgl_frameworkBundle; + ++ (nullable NSString *)mgl_frameworkBundleIdentifier; + ++ (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary; + +/// The relative path to the directory containing the SDK’s resource files, or +/// `nil` if the files are located directly within the bundle’s root directory. +@property (readonly, copy, nullable) NSString *mgl_resourcesDirectory; + +@end + +NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/NSBundle+MGLAdditions.m b/platform/darwin/src/NSBundle+MGLAdditions.m new file mode 100644 index 0000000000..e1f3e7c720 --- /dev/null +++ b/platform/darwin/src/NSBundle+MGLAdditions.m @@ -0,0 +1,40 @@ +#import "NSBundle+MGLAdditions.h" + +#import "MGLAccountManager.h" + +void mgl_linkBundleCategory() {} + +@implementation NSBundle (MGLAdditions) + ++ (instancetype)mgl_frameworkBundle { + NSBundle *bundle = [self bundleForClass:[MGLAccountManager class]]; + if (![bundle.infoDictionary[@"CFBundlePackageType"] isEqualToString:@"FMWK"] && !bundle.mgl_resourcesDirectory) { + // For static frameworks, the bundle is the containing application + // bundle but the resources are still in the framework bundle. + bundle = [NSBundle bundleWithPath:[bundle.privateFrameworksPath + stringByAppendingPathComponent:@"Mapbox.framework"]]; + } + return bundle; +} + ++ (nullable NSString *)mgl_frameworkBundleIdentifier { + return self.mgl_frameworkInfoDictionary[@"CFBundleIdentifier"]; +} + ++ (nullable NS_DICTIONARY_OF(NSString *, id) *)mgl_frameworkInfoDictionary { + NSBundle *bundle = self.mgl_frameworkBundle; + if (bundle.mgl_resourcesDirectory) { + NSString *infoPlistPath = [bundle pathForResource:@"Info" + ofType:@"plist" + inDirectory:bundle.mgl_resourcesDirectory]; + return [NSDictionary dictionaryWithContentsOfFile:infoPlistPath]; + } else { + return bundle.infoDictionary; + } +} + +- (NSString *)mgl_resourcesDirectory { + return [self pathForResource:@"Mapbox" ofType:@"bundle"] ? @"Mapbox.bundle" : nil; +} + +@end diff --git a/platform/darwin/src/NSProcessInfo+MGLAdditions.h b/platform/darwin/src/NSProcessInfo+MGLAdditions.h new file mode 100644 index 0000000000..ea231d4e6a --- /dev/null +++ b/platform/darwin/src/NSProcessInfo+MGLAdditions.h @@ -0,0 +1,13 @@ +#import <Foundation/Foundation.h> + +void mgl_linkProcessInfoCategory(); + +@interface NSProcessInfo (MGLAdditions) + +/** + Returns YES if the current process is Interface Builder’s helper process for + rendering designables. + */ +- (BOOL)mgl_isInterfaceBuilderDesignablesAgent; + +@end diff --git a/platform/darwin/src/NSProcessInfo+MGLAdditions.m b/platform/darwin/src/NSProcessInfo+MGLAdditions.m new file mode 100644 index 0000000000..3da2bf73ed --- /dev/null +++ b/platform/darwin/src/NSProcessInfo+MGLAdditions.m @@ -0,0 +1,17 @@ +#import "NSProcessInfo+MGLAdditions.h" + +void mgl_linkProcessInfoCategory() {} + +#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR + static NSString * const MGLIBDesignablesAgentProcessName = @"IBDesignablesAgentCocoaTouch"; +#elif TARGET_OS_MAC + static NSString * const MGLIBDesignablesAgentProcessName = @"IBDesignablesAgent"; +#endif + +@implementation NSProcessInfo (MGLAdditions) + +- (BOOL)mgl_isInterfaceBuilderDesignablesAgent { + return [self.processName isEqualToString:MGLIBDesignablesAgentProcessName]; +} + +@end |