summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLOfflineStorage.mm
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2016-03-06 23:57:09 -0800
committerMinh Nguyễn <mxn@1ec5.org>2016-03-10 17:08:58 -0800
commitf5ac63dfeccc185bc198b21f3ff6f87a9017848d (patch)
treeab9da2f017d31065cbf2d288b3e863cf9fa2c5db /platform/darwin/src/MGLOfflineStorage.mm
parente36218a8668316e8c1b0bcc06d43dad31461615c (diff)
downloadqtlocation-mapboxgl-f5ac63dfeccc185bc198b21f3ff6f87a9017848d.tar.gz
[ios, osx] Renamed offline classes
Renamed SDK classes related to offline viewing to more closely match the terminology used by mbgl and the Android SDK while remaining consistent with Cocoa naming principles.
Diffstat (limited to 'platform/darwin/src/MGLOfflineStorage.mm')
-rw-r--r--platform/darwin/src/MGLOfflineStorage.mm150
1 files changed, 150 insertions, 0 deletions
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm
new file mode 100644
index 0000000000..17537452a3
--- /dev/null
+++ b/platform/darwin/src/MGLOfflineStorage.mm
@@ -0,0 +1,150 @@
+#import "MGLOfflineStorage_Private.h"
+
+#import "MGLAccountManager_Private.h"
+#import "MGLGeometry_Private.h"
+#import "MGLOfflineTask_Private.h"
+#import "MGLOfflineRegion_Private.h"
+#import "MGLTilePyramidOfflineRegion.h"
+
+#include <mbgl/util/string.hpp>
+
+@interface MGLOfflineStorage ()
+
+@property (nonatomic) mbgl::DefaultFileSource *mbglFileSource;
+
+- (instancetype)initWithFileName:(NSString *)fileName NS_DESIGNATED_INITIALIZER;
+
+@end
+
+@implementation MGLOfflineStorage
+
++ (instancetype)sharedOfflineStorage {
+ static dispatch_once_t onceToken;
+ static MGLOfflineStorage *sharedOfflineStorage;
+ dispatch_once(&onceToken, ^{
+ sharedOfflineStorage = [[self alloc] initWithFileName:@"offline.db"];
+ });
+ return sharedOfflineStorage;
+}
+
+- (instancetype)initWithFileName:(NSString *)fileName {
+ if (self = [super init]) {
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ 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
+ forKeyPath:@"accessToken"
+ options:(NSKeyValueObservingOptionInitial |
+ NSKeyValueObservingOptionNew)
+ context:NULL];
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [[MGLAccountManager sharedManager] removeObserver:self forKeyPath:@"accessToken"];
+
+ delete _mbglFileSource;
+ _mbglFileSource = nullptr;
+}
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NS_DICTIONARY_OF(NSString *, id) *)change context:(__unused void *)context {
+ // Synchronize the file source’s access token with the global one in MGLAccountManager.
+ if ([keyPath isEqualToString:@"accessToken"] && object == [MGLAccountManager sharedManager]) {
+ NSString *accessToken = change[NSKeyValueChangeNewKey];
+ if (![accessToken isKindOfClass:[NSNull class]]) {
+ self.mbglFileSource->setAccessToken(accessToken.UTF8String);
+ }
+ }
+}
+
+- (void)addTaskForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflineTaskRegistrationCompletionHandler)completion {
+ if (![region conformsToProtocol:@protocol(MGLOfflineRegion_Private)]) {
+ [NSException raise:@"Unsupported region type" format:
+ @"Regions of type %@ are unsupported.", NSStringFromClass([region class])];
+ return;
+ }
+
+ const mbgl::OfflineTilePyramidRegionDefinition regionDefinition = [(id <MGLOfflineRegion_Private>)region offlineRegionDefinition];
+ mbgl::OfflineRegionMetadata metadata(context.length);
+ [context getBytes:&metadata[0] length:metadata.size()];
+ self.mbglFileSource->createOfflineRegion(regionDefinition, metadata, [&, completion](std::exception_ptr exception, mbgl::optional<mbgl::OfflineRegion> mbglOfflineRegion) {
+ NSError *error;
+ if (exception) {
+ NSString *errorDescription = @(mbgl::util::toString(exception).c_str());
+ error = [NSError errorWithDomain:MGLErrorDomain code:-1 userInfo:errorDescription ? @{
+ NSLocalizedDescriptionKey: errorDescription,
+ } : nil];
+ }
+ if (completion) {
+ MGLOfflineTask *task = [[MGLOfflineTask alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(*mbglOfflineRegion))];
+ dispatch_async(dispatch_get_main_queue(), [&, completion, error, task](void) {
+ completion(task, error);
+ });
+ }
+ });
+}
+
+- (void)removeTask:(MGLOfflineTask *)task withCompletionHandler:(MGLOfflineTaskRemovalCompletionHandler)completion {
+ self.mbglFileSource->deleteOfflineRegion(std::move(*task.mbglOfflineRegion), [&, completion](std::exception_ptr exception) {
+ NSError *error;
+ if (exception) {
+ error = [NSError errorWithDomain:MGLErrorDomain code:-1 userInfo:@{
+ NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()),
+ }];
+ }
+ if (completion) {
+ dispatch_async(dispatch_get_main_queue(), [&, completion, error](void) {
+ completion(error);
+ });
+ }
+ });
+}
+
+- (void)getTasksWithCompletionHandler:(MGLOfflineTasksRetrievalCompletionHandler)completion {
+ self.mbglFileSource->listOfflineRegions([&, completion](std::exception_ptr exception, mbgl::optional<std::vector<mbgl::OfflineRegion>> regions) {
+ NSError *error;
+ if (exception) {
+ error = [NSError errorWithDomain:MGLErrorDomain code:-1 userInfo:@{
+ NSLocalizedDescriptionKey: @(mbgl::util::toString(exception).c_str()),
+ }];
+ }
+ NSMutableArray *tasks;
+ if (regions) {
+ tasks = [NSMutableArray arrayWithCapacity:regions->size()];
+ for (mbgl::OfflineRegion &region : *regions) {
+ MGLOfflineTask *task = [[MGLOfflineTask alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(region))];
+ [tasks addObject:task];
+ }
+ }
+ if (completion) {
+ dispatch_async(dispatch_get_main_queue(), [&, completion, error, tasks](void) {
+ completion(tasks, error);
+ });
+ }
+ });
+}
+
+- (void)setMaximumAllowedMapboxTiles:(uint64_t)maximumCount {
+ _mbglFileSource->setOfflineMapboxTileCountLimit(maximumCount);
+}
+
+@end