diff options
author | Fabian Guerra Soto <fabian.guerra@mapbox.com> | 2018-09-17 15:31:43 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-17 15:31:43 -0700 |
commit | a938c3ef68af249bb3199bde2818436a0bff0952 (patch) | |
tree | 5301a86ea2e9b0b46d2684334f36a97dfa99a521 /platform/darwin/src | |
parent | 153e97c8e7cd03cdd0e94cb5e17a2723f417d973 (diff) | |
download | qtlocation-mapboxgl-a938c3ef68af249bb3199bde2818436a0bff0952.tar.gz |
[ios, macos] Offline regions merge. (#12791)
* [ios, macos] Add offline regions merge.
* [ios, macos] Update changelogs.
* [ios, macos] Fix refreshing the offline packs after new content is added.
* [ios, macos] Update MGLOfflineStorage's add contents of file documentation.
* [ios, macos] Add MGLOfflineStorage test cases for adding file contents.
* [ios, macos] Add offline merge test database.
* [ios, macos] Add packs parameter to MGLBatchedOfflinePackAdditionCompletionHandler.
* [core] Fix a query mege duplication.
* [ios, macos] Remove unnecessary pack iteration.
* [ios, macos] Fix packs update KVO notifications.
* [ios, macos] Add localization strings.
* [core] Fix query readability.
* [ios, macos] Fix MGLOfflineStorageTest, cleanup the cache database after the test.
* [ios, macos] Fix offline packs, updating triggers a crash.
Diffstat (limited to 'platform/darwin/src')
-rw-r--r-- | platform/darwin/src/MGLOfflineStorage.h | 48 | ||||
-rw-r--r-- | platform/darwin/src/MGLOfflineStorage.mm | 83 |
2 files changed, 131 insertions, 0 deletions
diff --git a/platform/darwin/src/MGLOfflineStorage.h b/platform/darwin/src/MGLOfflineStorage.h index f8ea6e7453..d512c60845 100644 --- a/platform/darwin/src/MGLOfflineStorage.h +++ b/platform/darwin/src/MGLOfflineStorage.h @@ -135,6 +135,18 @@ typedef void (^MGLOfflinePackAdditionCompletionHandler)(MGLOfflinePack * _Nullab typedef void (^MGLOfflinePackRemovalCompletionHandler)(NSError * _Nullable error); /** + A block to be called once the contents of a file are copied into the current packs. + + @param fileURL The file URL of the offline database containing the offline packs + that were copied. + @param packs An array of all known offline packs, or `nil` if there was an error + creating or adding the pack. + @param error A pointer to an error object (if any) indicating why the pack could + not be created or added. + */ +typedef void (^MGLBatchedOfflinePackAdditionCompletionHandler)(NSURL *fileURL, NSArray<MGLOfflinePack *> * _Nullable packs, NSError * _Nullable error); + +/** The type of resource that is requested. */ typedef NS_ENUM(NSUInteger, MGLResourceKind) { @@ -174,6 +186,42 @@ MGL_EXPORT */ @property (class, nonatomic, readonly) MGLOfflineStorage *sharedOfflineStorage; +#pragma mark - Adding Contents of File + +/** + Adds the offline packs located at the given file path to offline storage. + + The file must be a valid offline region database bundled with the application + or downloaded separately. + + The resulting packs are added or updated to the shared offline storage object’s `packs` + property, then the `completion` block is executed. + + @param filePath A string representation of the file path. The file path must be + writable as schema updates may be perfomed. + @param completion The completion handler to call once the contents of the given + file has been added to offline storage. This handler is executed asynchronously + on the main queue. + */ +- (void)addContentsOfFile:(NSString *)filePath withCompletionHandler:(nullable MGLBatchedOfflinePackAdditionCompletionHandler)completion; + +/** + Adds the offline packs located at the given URL to offline storage. + + The file must be a valid offline region database bundled with the application + or downloaded separately. + + The resulting packs are added or updated to the shared offline storage object’s `packs` + property, then the `completion` block is executed. + + @param fileURL A file URL specifying the file to add. URL should be a valid system path. + The file URL must be writable as schema updates may be performed. + @param completion The completion handler to call once the contents of the given + file has been added to offline storage. This handler is executed asynchronously + on the main queue. + */ +- (void)addContentsOfURL:(NSURL *)fileURL withCompletionHandler:(nullable MGLBatchedOfflinePackAdditionCompletionHandler)completion; + #pragma mark - Accessing the Delegate /** diff --git a/platform/darwin/src/MGLOfflineStorage.mm b/platform/darwin/src/MGLOfflineStorage.mm index 93a6da36c4..fd6dd2f998 100644 --- a/platform/darwin/src/MGLOfflineStorage.mm +++ b/platform/darwin/src/MGLOfflineStorage.mm @@ -264,6 +264,89 @@ const MGLExceptionName MGLUnsupportedRegionTypeException = @"MGLUnsupportedRegio } } +#pragma mark Offline merge methods + +- (void)addContentsOfFile:(NSString *)filePath withCompletionHandler:(MGLBatchedOfflinePackAdditionCompletionHandler)completion { + NSURL *fileURL = [NSURL fileURLWithPath:filePath]; + + [self addContentsOfURL:fileURL withCompletionHandler:completion]; + +} + +- (void)addContentsOfURL:(NSURL *)fileURL withCompletionHandler:(MGLBatchedOfflinePackAdditionCompletionHandler)completion { + + NSFileManager *fileManager = [NSFileManager defaultManager]; + + if (!fileURL.isFileURL) { + [NSException raise:NSInvalidArgumentException format:@"%@ must be a valid file path", fileURL.absoluteString]; + } + if (![fileManager isWritableFileAtPath:fileURL.path]) { + [NSException raise:NSInvalidArgumentException format:@"The file path: %@ must be writable", fileURL.absoluteString]; + } + + __weak MGLOfflineStorage *weakSelf = self; + [self _addContentsOfFile:fileURL.path withCompletionHandler:^(NSArray<MGLOfflinePack *> * _Nullable packs, NSError * _Nullable error) { + if (packs) { + NSMutableDictionary *packsByIdentifier = [NSMutableDictionary dictionary]; + + MGLOfflineStorage *strongSelf = weakSelf; + for (MGLOfflinePack *pack in packs) { + [packsByIdentifier setObject:pack forKey:@(pack.mbglOfflineRegion->getID())]; + } + + id mutablePacks = [strongSelf mutableArrayValueForKey:@"packs"]; + NSMutableIndexSet *replaceIndexSet = [NSMutableIndexSet indexSet]; + NSMutableArray *replacePacksArray = [NSMutableArray array]; + [strongSelf.packs enumerateObjectsUsingBlock:^(MGLOfflinePack * _Nonnull pack, NSUInteger idx, BOOL * _Nonnull stop) { + MGLOfflinePack *newPack = packsByIdentifier[@(pack.mbglOfflineRegion->getID())]; + if (newPack) { + MGLOfflinePack *previousPack = [mutablePacks objectAtIndex:idx]; + [previousPack invalidate]; + [replaceIndexSet addIndex:idx]; + [replacePacksArray addObject:[packsByIdentifier objectForKey:@(newPack.mbglOfflineRegion->getID())]]; + [packsByIdentifier removeObjectForKey:@(newPack.mbglOfflineRegion->getID())]; + } + + }]; + + if (replaceIndexSet.count > 0) { + [mutablePacks replaceObjectsAtIndexes:replaceIndexSet withObjects:replacePacksArray]; + } + + [mutablePacks addObjectsFromArray:packsByIdentifier.allValues]; + } + if (completion) { + completion(fileURL, packs, error); + } + }]; +} + +- (void)_addContentsOfFile:(NSString *)filePath withCompletionHandler:(void (^)(NSArray<MGLOfflinePack *> * _Nullable packs, NSError * _Nullable error))completion { + self.mbglFileSource->mergeOfflineRegions(std::string(static_cast<const char *>([filePath UTF8String])), [&, completion, filePath](mbgl::expected<mbgl::OfflineRegions, std::exception_ptr> result) { + NSError *error; + NSMutableArray *packs; + if (!result) { + NSString *description = [NSString stringWithFormat:NSLocalizedStringWithDefaultValue(@"ADD_FILE_CONTENTS_FAILED_DESC", @"Foundation", nil, @"Unable to add offline packs from the file at %@.", @"User-friendly error description"), filePath]; + error = [NSError errorWithDomain:MGLErrorDomain code:-1 userInfo:@{ + NSLocalizedDescriptionKey: description, + NSLocalizedFailureReasonErrorKey: @(mbgl::util::toString(result.error()).c_str()) + }]; + } else { + auto& regions = result.value(); + packs = [NSMutableArray arrayWithCapacity:regions.size()]; + for (auto ®ion : regions) { + MGLOfflinePack *pack = [[MGLOfflinePack alloc] initWithMBGLRegion:new mbgl::OfflineRegion(std::move(region))]; + [packs addObject:pack]; + } + } + if (completion) { + dispatch_async(dispatch_get_main_queue(), [&, completion, error, packs](void) { + completion(packs, error); + }); + } + }); +} + #pragma mark Pack management methods - (void)addPackForRegion:(id <MGLOfflineRegion>)region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion { |