Files
MapLibreParticleLab/platform/darwin/src/MGLSource.mm
Minh Nguyễn ff0f7a8754 [ios, macos] Refined source removal errors
Clarified and copyedited the descriptions of errors that are raised when attempting to remove a source from a style. Worded the changelog entry more generically because the same method in Swift throws an error instead of returning.

A mismatch would occur if the identifier is used by a different source than the one being removed. An application could cause this error to occur by keeping a reference to an MGLSource after changing the style URL of an MGLMapView. Another way would be to remove a source from the style, add another source to the style with the same identifier, then attempt to re-remove the original source from the style.
2018-12-04 22:29:39 -08:00

101 lines
3.8 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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>
#include <mbgl/style/source.hpp>
@interface MGLSource ()
// Even though this class is abstract, MGLStyle uses it to represent some
// special internal source types like mbgl::AnnotationSource.
@property (nonatomic, readonly) mbgl::style::Source *rawSource;
@property (nonatomic, readonly, weak) MGLMapView *mapView;
@end
@implementation MGLSource {
std::unique_ptr<mbgl::style::Source> _pendingSource;
}
- (instancetype)initWithIdentifier:(NSString *)identifier
{
if (self = [super init]) {
_identifier = identifier;
}
return self;
}
- (instancetype)initWithRawSource:(mbgl::style::Source *)rawSource mapView:(MGLMapView *)mapView {
NSString *identifier = @(rawSource->getID().c_str());
if (self = [self initWithIdentifier:identifier]) {
_rawSource = rawSource;
_rawSource->peer = SourceWrapper { self };
_mapView = mapView;
}
return self;
}
- (instancetype)initWithPendingSource:(std::unique_ptr<mbgl::style::Source>)pendingSource {
if (self = [self initWithRawSource:pendingSource.get() mapView:nil]) {
_pendingSource = std::move(pendingSource);
}
return self;
}
- (void)addToMapView:(MGLMapView *)mapView {
if (_pendingSource == nullptr) {
[NSException raise:MGLRedundantSourceException
format:@"This instance %@ was already added to %@. Adding the same source instance " \
"to the style more than once is invalid.", self, mapView.style];
}
_mapView = mapView;
_mapView.style.rawStyle->addSource(std::move(_pendingSource));
}
- (BOOL)removeFromMapView:(MGLMapView *)mapView error:(NSError * __nullable * __nullable)outError {
BOOL removed = NO;
if (self.rawSource == mapView.style.rawStyle->getSource(self.identifier.UTF8String)) {
auto removedSource = mapView.style.rawStyle->removeSource(self.identifier.UTF8String);
if (removedSource) {
removed = YES;
_pendingSource = std::move(removedSource);
_mapView = nil;
} else if (outError) {
NSString *localizedDescription = [NSString stringWithFormat:
NSLocalizedStringWithDefaultValue(@"REMOVE_SRC_FAIL_IN_USE_FMT", @"Foundation", nil, @"The source “%@” can’t be removed while it is in use.", @"User-friendly error description; first placeholder is the source’s identifier"),
self.identifier];
*outError = [NSError errorWithDomain:MGLErrorDomain
code:MGLErrorCodeSourceIsInUseCannotRemove
userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }];
}
} else if (outError) {
// TODO: Consider raising an exception here
NSString *localizedDescription = [NSString stringWithFormat:
NSLocalizedStringWithDefaultValue(@"REMOVE_SRC_FAIL_MISMATCH_FMT", @"Foundation", nil, @"The source can’t be removed because its identifier, “%@”, belongs to a different source in this style.", @"User-friendly error description"),
self.identifier];
*outError = [NSError errorWithDomain:MGLErrorDomain
code:MGLErrorCodeSourceIdentifierMismatch
userInfo:@{ NSLocalizedDescriptionKey : localizedDescription }];
}
return removed;
}
- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p; identifier = %@>",
NSStringFromClass([self class]), (void *)self, self.identifier];
}
@end