summaryrefslogtreecommitdiff
path: root/platform/darwin
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin')
-rw-r--r--platform/darwin/src/MGLOfflineStorage.mm122
-rw-r--r--platform/darwin/test/MGLOfflineStorageTests.m11
2 files changed, 84 insertions, 49 deletions
diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm
index a59fb69943..dd15920eab 100644
--- a/platform/darwin/src/MGLOfflineStorage.mm
+++ b/platform/darwin/src/MGLOfflineStorage.mm
@@ -40,58 +40,92 @@ NSString * const MGLOfflinePackMaximumCountUserInfoKey = @"MaximumCount";
return sharedOfflineStorage;
}
+/**
+ Returns the file URL to the offline cache, with the option to omit the private
+ subdirectory for legacy (v3.2.0 - v3.2.3) migration purposes.
+
+ The cache is located in a directory specific to the application, so that packs
+ downloaded by other applications don’t count toward this application’s limits.
+
+ The cache is located at:
+ ~/Library/Application Support/tld.app.bundle.id/.mapbox/cache.db
+
+ The subdirectory-less cache was located at:
+ ~/Library/Application Support/tld.app.bundle.id/cache.db
+ */
++ (NSURL *)cacheURLIncludingSubdirectory:(BOOL)useSubdirectory {
+ NSURL *cacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
+ inDomain:NSUserDomainMask
+ appropriateForURL:nil
+ create:YES
+ error:nil];
+ NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
+ if (!bundleIdentifier) {
+ // There’s no main bundle identifier when running in a unit test bundle.
+ bundleIdentifier = [NSBundle bundleForClass:self].bundleIdentifier;
+ }
+ cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier];
+ if (useSubdirectory) {
+ cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:@".mapbox"];
+ }
+ [[NSFileManager defaultManager] createDirectoryAtURL:cacheDirectoryURL
+ withIntermediateDirectories:YES
+ attributes:nil
+ error:nil];
+ if (useSubdirectory) {
+ // Avoid backing up the offline cache onto iCloud, because it can be
+ // redownloaded. Ideally, we’d even put the ambient cache in Caches, so
+ // it can be reclaimed by the system when disk space runs low. But
+ // unfortunately it has to live in the same file as offline resources.
+ [cacheDirectoryURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:NULL];
+ }
+ return [cacheDirectoryURL URLByAppendingPathComponent:MGLOfflineStorageFileName];
+}
+
+/**
+ Returns the absolute path to the location where v3.2.0-beta.1 placed the
+ offline cache.
+ */
++ (NSString *)legacyCachePath {
+#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+ // ~/Documents/offline.db
+ NSArray *legacyPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSString *legacyCachePath = [legacyPaths.firstObject stringByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1];
+#elif TARGET_OS_MAC
+ // ~/Library/Caches/tld.app.bundle.id/offline.db
+ NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
+ NSURL *legacyCacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory
+ inDomain:NSUserDomainMask
+ appropriateForURL:nil
+ create:NO
+ error:nil];
+ legacyCacheDirectoryURL = [legacyCacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier];
+ NSURL *legacyCacheURL = [legacyCacheDirectoryURL URLByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1];
+ NSString *legacyCachePath = legacyCacheURL ? legacyCacheURL.path : @"";
+#endif
+ return legacyCachePath;
+}
+
- (instancetype)init {
if (self = [super init]) {
- // Place the cache in a location specific to the application, so that
- // packs downloaded by other applications don’t count toward this
- // application’s limits.
- // ~/Library/Application Support/tld.app.bundle.id/cache.db
- NSURL *cacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSApplicationSupportDirectory
- inDomain:NSUserDomainMask
- appropriateForURL:nil
- create:YES
- error:nil];
- NSString *bundleIdentifier = [NSBundle mainBundle].bundleIdentifier;
- if (!bundleIdentifier) {
- // There’s no main bundle identifier when running in a unit test bundle.
- bundleIdentifier = [NSBundle bundleForClass:[self class]].bundleIdentifier;
- }
- cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier];
- [[NSFileManager defaultManager] createDirectoryAtURL:cacheDirectoryURL
- withIntermediateDirectories:YES
- attributes:nil
- error:nil];
- NSURL *cacheURL = [cacheDirectoryURL URLByAppendingPathComponent:MGLOfflineStorageFileName];
- NSString *cachePath = cacheURL ? cacheURL.path : @"";
-
+ NSURL *cacheURL = [[self class] cacheURLIncludingSubdirectory:YES];
+ NSString *cachePath = cacheURL.path ?: @"";
+
// Move the offline cache from v3.2.0-beta.1 to a location that can also
// be used for ambient caching.
-#if TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
- // ~/Documents/offline.db
- NSArray *legacyPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *legacyCachePath = [legacyPaths.firstObject stringByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1];
-#elif TARGET_OS_MAC
- // ~/Library/Caches/tld.app.bundle.id/offline.db
- NSURL *legacyCacheDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSCachesDirectory
- inDomain:NSUserDomainMask
- appropriateForURL:nil
- create:NO
- error:nil];
- legacyCacheDirectoryURL = [legacyCacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier];
- NSURL *legacyCacheURL = [legacyCacheDirectoryURL URLByAppendingPathComponent:MGLOfflineStorageFileName3_2_0_beta_1];
- NSString *legacyCachePath = legacyCacheURL ? legacyCacheURL.path : @"";
-#endif
if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath]) {
+ NSString *legacyCachePath = [[self class] legacyCachePath];
[[NSFileManager defaultManager] moveItemAtPath:legacyCachePath toPath:cachePath error:NULL];
}
-
- _mbglFileSource = new mbgl::DefaultFileSource(cachePath.UTF8String, [NSBundle mainBundle].resourceURL.path.UTF8String);
- // Avoid backing up the offline cache onto iCloud, because it can be
- // redownloaded. Ideally, we’d even put the ambient cache in Caches, so
- // it can be reclaimed by the system when disk space runs low. But
- // unfortunately it has to live in the same file as offline resources.
- [cacheURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:NULL];
+ // Move the offline file cache from v3.2.x path to a subdirectory that
+ // can be reliably excluded from backups.
+ if (![[NSFileManager defaultManager] fileExistsAtPath:cachePath]) {
+ NSURL *subdirectorylessCacheURL = [[self class] cacheURLIncludingSubdirectory:NO];
+ [[NSFileManager defaultManager] moveItemAtPath:subdirectorylessCacheURL.path toPath:cachePath error:NULL];
+ }
+
+ _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/test/MGLOfflineStorageTests.m b/platform/darwin/test/MGLOfflineStorageTests.m
index 415039c527..e2346c5f61 100644
--- a/platform/darwin/test/MGLOfflineStorageTests.m
+++ b/platform/darwin/test/MGLOfflineStorageTests.m
@@ -106,17 +106,18 @@
// Unit tests don't use the main bundle; use com.mapbox.ios.sdk instead.
NSString *bundleIdentifier = [NSBundle bundleForClass:[MGLMapView class]].bundleIdentifier;
cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:bundleIdentifier];
- XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:cacheDirectoryURL.path], @"Cache directory should exist.");
+ cacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:@".mapbox"];
+ XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:cacheDirectoryURL.path], @"Cache subdirectory should exist.");
NSURL *cacheURL = [cacheDirectoryURL URLByAppendingPathComponent:@"cache.db"];
XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:cacheURL.path], @"Cache database should exist.");
NSError *error = nil;
NSNumber *exclusionFlag = nil;
- [cacheURL getResourceValue:&exclusionFlag
- forKey:NSURLIsExcludedFromBackupKey
- error:&error];
- XCTAssertTrue(exclusionFlag && [exclusionFlag boolValue], @"Backup exclusion flag should be set for cache database.");
+ [cacheDirectoryURL getResourceValue:&exclusionFlag
+ forKey:NSURLIsExcludedFromBackupKey
+ error:&error];
+ XCTAssertTrue(exclusionFlag && [exclusionFlag boolValue], @"Backup exclusion flag should be set for the directory containing the cache database.");
XCTAssertNil(error, @"No errors should be returned when checking backup exclusion flag.");
}