diff options
author | Julian Rex <julian.rex@gmail.com> | 2018-11-20 10:26:09 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-20 10:26:09 -0500 |
commit | 90f609ca8fe92f89374a7c1438511cde0f72195a (patch) | |
tree | 575483facd4204f0da290a5c37da620107737f18 /platform/darwin | |
parent | 9ac444a08d9701dc7b0da41859842a77d7be8e00 (diff) | |
download | qtlocation-mapboxgl-90f609ca8fe92f89374a7c1438511cde0f72195a.tar.gz |
[ios, macos] Added `-(BOOL)[MGLStyle removeSource:error:]` that provides an NSError. (#13399)
Diffstat (limited to 'platform/darwin')
-rw-r--r-- | platform/darwin/resources/Base.lproj/Foundation.strings | 6 | ||||
-rw-r--r-- | platform/darwin/src/MGLSource.mm | 35 | ||||
-rw-r--r-- | platform/darwin/src/MGLSource_Private.h | 2 | ||||
-rw-r--r-- | platform/darwin/src/MGLStyle.h | 21 | ||||
-rw-r--r-- | platform/darwin/src/MGLStyle.mm | 9 | ||||
-rw-r--r-- | platform/darwin/src/MGLTypes.h | 6 | ||||
-rw-r--r-- | platform/darwin/test/MGLStyleTests.mm | 7 |
7 files changed, 79 insertions, 7 deletions
diff --git a/platform/darwin/resources/Base.lproj/Foundation.strings b/platform/darwin/resources/Base.lproj/Foundation.strings index 19bfe750e6..360e3c8562 100644 --- a/platform/darwin/resources/Base.lproj/Foundation.strings +++ b/platform/darwin/resources/Base.lproj/Foundation.strings @@ -298,3 +298,9 @@ /* OpenStreetMap short name attribution */ "OSM_SHORT_NAME" = "OSM"; +/* User-friendly error description */ +"REMOVE_SRC_FAIL_IN_USE_FMT" = "Source '%@' is in use, cannot remove."; + +/* User-friendly error description */ +"REMOVE_SRC_FAIL_MISMATCH_FMT" = "Identifier '%1$@' does not match source identifier '%2$s'"; + diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm index a32e223782..62d3cfa808 100644 --- a/platform/darwin/src/MGLSource.mm +++ b/platform/darwin/src/MGLSource.mm @@ -1,6 +1,7 @@ #import "MGLSource_Private.h" #import "MGLStyle_Private.h" #import "MGLMapView_Private.h" +#import "NSBundle+MGLAdditions.h" #include <mbgl/style/style.hpp> #include <mbgl/map/map.hpp> @@ -57,11 +58,39 @@ _mapView.style.rawStyle->addSource(std::move(_pendingSource)); } -- (void)removeFromMapView:(MGLMapView *)mapView { +- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError { + BOOL removed = NO; + if (self.rawSource == mapView.style.rawStyle->getSource(self.identifier.UTF8String)) { - _pendingSource = mapView.style.rawStyle->removeSource(self.identifier.UTF8String); - _mapView = nil; + + auto removedSource = mapView.style.rawStyle->removeSource(self.identifier.UTF8String); + + if (removedSource) { + removed = YES; + _pendingSource = std::move(removedSource); + _mapView = nil; + } else if (outError) { + NSString *format = NSLocalizedStringWithDefaultValue(@"REMOVE_SRC_FAIL_IN_USE_FMT", @"Foundation", nil, @"Source '%@' is in use, cannot remove.", @"User-friendly error description"); + NSString *localizedDescription = [NSString stringWithFormat:format, self.identifier]; + + *outError = [NSError errorWithDomain:MGLErrorDomain + code:MGLErrorCodeSourceIsInUseCannotRemove + userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }]; + } } + else if (outError) { + // Consider raising an exception here + NSString *format = NSLocalizedStringWithDefaultValue(@"REMOVE_SRC_FAIL_MISMATCH_FMT", @"Foundation", nil, @"Identifier '%@' does not match source identifier '%s'", @"User-friendly error description"); + NSString *localizedDescription = [NSString stringWithFormat:format, + self.identifier, + self.rawSource ? self.rawSource->getID().c_str() : "(null)"]; + + *outError = [NSError errorWithDomain:MGLErrorDomain + code:MGLErrorCodeSourceIdentifierMismatch + userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }]; + } + + return removed; } - (NSString *)description { diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h index d7d1f66641..af14c11b90 100644 --- a/platform/darwin/src/MGLSource_Private.h +++ b/platform/darwin/src/MGLSource_Private.h @@ -67,7 +67,7 @@ struct SourceWrapper { to the `MGLSource` instance and the unique_ptr reference is valid again. It is safe to add the source back to the style after it is removed. */ -- (void)removeFromMapView:(MGLMapView *)mapView; +- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError; @end diff --git a/platform/darwin/src/MGLStyle.h b/platform/darwin/src/MGLStyle.h index fcbd318b18..7621db0ad5 100644 --- a/platform/darwin/src/MGLStyle.h +++ b/platform/darwin/src/MGLStyle.h @@ -318,6 +318,27 @@ MGL_EXPORT */ - (void)removeSource:(MGLSource *)source; +/** + Removes a source from the current style. + + @note Source identifiers are not guaranteed to exist across styles or different + versions of the same style. Applications that use this API must first set the + style URL to an explicitly versioned style using a convenience method like + `+[MGLStyle outdoorsStyleURLWithVersion:]`, `MGLMapView`’s “Style URL” + inspectable in Interface Builder, or a manually constructed `NSURL`. This + approach also avoids source identifer name changes that will occur in the default + style’s sources over time. + + @param source The source to remove from the current style. + @param outError Upon return, if an error has occurred, a pointer to an `NSError` + object describing the error. Pass in `NULL` to ignore any error. + + @return `YES` if `source` was removed successfully. If `NO`, `outError` contains + an `NSError` object describing the problem. + */ +- (BOOL)removeSource:(MGLSource *)source error:(NSError * __nullable * __nullable)outError; + + #pragma mark Managing Style Layers /** diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 4c98fd332b..244d09ea14 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -219,16 +219,23 @@ static_assert(6 == mbgl::util::default_styles::numOrderedStyles, - (void)removeSource:(MGLSource *)source { + [self removeSource:source error:nil]; +} + +- (BOOL)removeSource:(MGLSource *)source error:(NSError * __nullable * __nullable)outError { MGLLogDebug(@"Removing source: %@", source); + if (!source.rawSource) { [NSException raise:NSInvalidArgumentException format: @"The source %@ cannot be removed from the style. " @"Make sure the source was created as a member of a concrete subclass of MGLSource.", source]; } - [source removeFromMapView:self.mapView]; + + return [source removeFromMapView:self.mapView error:outError]; } + - (nullable NSArray<MGLAttributionInfo *> *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { // It’d be incredibly convenient to use -sources here, but this operation // depends on the sources being sorted in ascending order by creation, as diff --git a/platform/darwin/src/MGLTypes.h b/platform/darwin/src/MGLTypes.h index 1cf52f20ce..5aee79bd82 100644 --- a/platform/darwin/src/MGLTypes.h +++ b/platform/darwin/src/MGLTypes.h @@ -49,7 +49,11 @@ typedef NS_ENUM(NSInteger, MGLErrorCode) { /** An attempt to load the style failed. */ MGLErrorCodeLoadStyleFailed = 5, /** An error occurred while snapshotting the map. */ - MGLErrorCodeSnapshotFailed = 6 + MGLErrorCodeSnapshotFailed = 6, + /** Source is in use and cannot be removed */ + MGLErrorCodeSourceIsInUseCannotRemove = 7, + /** Source is in use and cannot be removed */ + MGLErrorCodeSourceIdentifierMismatch = 8 }; /** Options for enabling debugging features in an `MGLMapView` instance. */ diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index d317292096..ce7e3036a1 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -237,7 +237,12 @@ [self.style addLayer:fillLayer]; // Attempt to remove the raster tile source - [self.style removeSource:rasterTileSource]; + NSError *error; + BOOL result = [self.style removeSource:rasterTileSource error:&error]; + + XCTAssertFalse(result); + XCTAssertEqualObjects(error.domain, MGLErrorDomain); + XCTAssertEqual(error.code, MGLErrorCodeSourceIsInUseCannotRemove); // Ensure it is still there XCTAssertTrue([[self.style sourceWithIdentifier:rasterTileSource.identifier] isMemberOfClass:[MGLRasterTileSource class]]); |