summaryrefslogtreecommitdiff
path: root/platform/darwin
diff options
context:
space:
mode:
authorJulian Rex <julian.rex@gmail.com>2018-11-20 10:26:09 -0500
committerGitHub <noreply@github.com>2018-11-20 10:26:09 -0500
commit90f609ca8fe92f89374a7c1438511cde0f72195a (patch)
tree575483facd4204f0da290a5c37da620107737f18 /platform/darwin
parent9ac444a08d9701dc7b0da41859842a77d7be8e00 (diff)
downloadqtlocation-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.strings6
-rw-r--r--platform/darwin/src/MGLSource.mm35
-rw-r--r--platform/darwin/src/MGLSource_Private.h2
-rw-r--r--platform/darwin/src/MGLStyle.h21
-rw-r--r--platform/darwin/src/MGLStyle.mm9
-rw-r--r--platform/darwin/src/MGLTypes.h6
-rw-r--r--platform/darwin/test/MGLStyleTests.mm7
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]]);