From a938c3ef68af249bb3199bde2818436a0bff0952 Mon Sep 17 00:00:00 2001 From: Fabian Guerra Soto Date: Mon, 17 Sep 2018 15:31:43 -0700 Subject: [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. --- platform/darwin/src/MGLOfflineStorage.mm | 83 ++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'platform/darwin/src/MGLOfflineStorage.mm') 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 * _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 * _Nullable packs, NSError * _Nullable error))completion { + self.mbglFileSource->mergeOfflineRegions(std::string(static_cast([filePath UTF8String])), [&, completion, filePath](mbgl::expected 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 )region withContext:(NSData *)context completionHandler:(MGLOfflinePackAdditionCompletionHandler)completion { -- cgit v1.2.1