diff --git a/platform/darwin/src/MGLMapSnapshotter.h b/platform/darwin/src/MGLMapSnapshotter.h index de509f73f47..2bd9d99fe0f 100644 --- a/platform/darwin/src/MGLMapSnapshotter.h +++ b/platform/darwin/src/MGLMapSnapshotter.h @@ -173,6 +173,8 @@ typedef void (^MGLMapSnapshotCompletionHandler)(MGLMapSnapshot* _Nullable snapsh MGL_EXPORT @interface MGLMapSnapshotter : NSObject +- (instancetype)init NS_UNAVAILABLE; + /** Initializes and returns a map snapshotter object that produces snapshots according to the given options. @@ -180,7 +182,7 @@ MGL_EXPORT @param options The options to use when generating a map snapshot. @return An initialized map snapshotter. */ -- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options; +- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options NS_DESIGNATED_INITIALIZER; /** Starts the snapshot creation and executes the specified block with the result. diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm index 3c5e36f8f21..639a3b62eea 100644 --- a/platform/darwin/src/MGLMapSnapshotter.mm +++ b/platform/darwin/src/MGLMapSnapshotter.mm @@ -117,6 +117,7 @@ - (CLLocationCoordinate2D)coordinateForPoint:(NSPoint)point @interface MGLMapSnapshotter() @property (nonatomic) BOOL cancelled; +@property (nonatomic) BOOL terminated; @property (nonatomic) dispatch_queue_t resultQueue; @property (nonatomic, copy) MGLMapSnapshotCompletionHandler completion; + (void)completeWithErrorCode:(MGLErrorCode)errorCode description:(nonnull NSString*)description onQueue:(dispatch_queue_t)queue completion:(MGLMapSnapshotCompletionHandler)completion; @@ -129,6 +130,8 @@ @implementation MGLMapSnapshotter { } - (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + if (_completion) { MGLAssert(_snapshotCallback, @"Snapshot in progress - there should be a valid callback"); @@ -139,16 +142,41 @@ - (void)dealloc { } } + +- (instancetype)init { + NSAssert(NO, @"Please use -[MGLMapSnapshotter initWithOptions:]"); + [super doesNotRecognizeSelector:_cmd]; + return nil; +} + - (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options { MGLLogDebug(@"Initializing withOptions: %@", options); self = [super init]; if (self) { [self setOptions:options]; +#if TARGET_OS_IPHONE + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:UIApplicationWillTerminateNotification object:nil]; +#else + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillTerminate:) name:NSApplicationWillTerminateNotification object:nil]; +#endif } return self; } +- (void)applicationWillTerminate:(NSNotification *)notification +{ + if (self.completion) { + [self cancel]; + } + + _mbglMapSnapshotter.reset(); + _snapshotCallback.reset(); + _mbglThreadPool.reset(); + + self.terminated = YES; +} + - (void)startWithCompletionHandler:(MGLMapSnapshotCompletionHandler)completion { MGLLogDebug(@"Starting withCompletionHandler: %@", completion); @@ -167,7 +195,12 @@ - (void)startWithQueue:(dispatch_queue_t)queue completionHandler:(MGLMapSnapshot [NSException raise:NSInternalInconsistencyException format:@"Already started this snapshotter."]; } - + + if (self.terminated) { + [NSException raise:NSInternalInconsistencyException + format:@"Starting a snapshotter after application termination is not supported."]; + } + self.completion = completion; self.resultQueue = queue; self.cancelled = NO; @@ -539,7 +572,18 @@ + (void)completeWithErrorCode:(MGLErrorCode)errorCode description:(nonnull NSStr - (void)setOptions:(MGLMapSnapshotOptions *)options { + if (_terminated) { + [NSException raise:NSInternalInconsistencyException + format:@"Calling MGLMapSnapshotter.options after application termination is not supported."]; + } + MGLLogDebug(@"Setting options: %@", options); + + if (_completion) { + [self cancel]; + } + + _cancelled = NO; _options = options; mbgl::DefaultFileSource *mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; _mbglThreadPool = mbgl::sharedThreadPool(); diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md index 2352879dae3..a93555ebe89 100644 --- a/platform/ios/CHANGELOG.md +++ b/platform/ios/CHANGELOG.md @@ -9,6 +9,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT * Added `MGLLoggingConfiguration` and `MGLLoggingBlockHandler` that handle error and fault events produced by the SDK. ([#13235](https://github.com/mapbox/mapbox-gl-native/pull/13235)) * This SDK’s dynamic framework now has a bundle identifier of `com.mapbox.Mapbox`. ([#12857](https://github.com/mapbox/mapbox-gl-native/pull/12857)) * Modified the behavior of the map view so that programmatic camera transitions can no longer be interrupted by user interaction when `MGLMapView.zoomEnabled`, `MGLMapView.rotateEnabled`, `MGLMapView.scrollEnabled`, and `MGLMapView.pitchEnabled` are set to false. ([#13362](https://github.com/mapbox/mapbox-gl-native/pull/13362)) +* Fixed random crashes during app termination. ([#13367](https://github.com/mapbox/mapbox-gl-native/pull/13367)) * Added `-[MGLStyle removeSource:error:]` that returns a `BOOL` indicating success (and an optional `NSError` in case of failure). ([#13399](https://github.com/mapbox/mapbox-gl-native/pull/13399)) ## 4.6.0 - November 7, 2018 diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 3520051434d..f058b75dc97 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -1986,7 +1986,7 @@ - (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(idgetStyle().getURL().c_str()).mgl_stringOrNilIfEmpty; + if (!_mbglMap) + { + NSAssert(self.terminated, @"_mbglMap should only be unavailable during app termination"); + return self.residualStyleURL; + } + + NSString *styleURLString = @(self.mbglMap.getStyle().getURL().c_str()).mgl_stringOrNilIfEmpty; MGLAssert(styleURLString || _isTargetingInterfaceBuilder, @"Invalid style URL string %@", styleURLString); return styleURLString ? [NSURL URLWithString:styleURLString] : nil; } @@ -388,19 +403,24 @@ - (void)setStyleURL:(nullable NSURL *)styleURL MGLLogDebug(@"Setting styleURL: %@", styleURL); styleURL = styleURL.mgl_URLByStandardizingScheme; self.style = nil; - _mbglMap->getStyle().loadURL([[styleURL absoluteString] UTF8String]); + self.mbglMap.getStyle().loadURL([[styleURL absoluteString] UTF8String]); } - (IBAction)reloadStyle:(__unused id)sender { MGLLogInfo(@"Reloading style."); NSURL *styleURL = self.styleURL; - _mbglMap->getStyle().loadURL(""); + self.mbglMap.getStyle().loadURL(""); self.styleURL = styleURL; } -- (mbgl::Map *)mbglMap +- (mbgl::Map &)mbglMap { - return _mbglMap; + if (!_mbglMap) + { + [NSException raise:MGLUnderlyingMapUnavailableException + format:@"The underlying map is not available - this happens during app termination"]; + } + return *_mbglMap; } - (mbgl::Renderer *)renderer @@ -447,6 +467,8 @@ - (void)commonInit auto renderer = std::make_unique(*_mbglView, config.scaleFactor, *config.fileSource, *_mbglThreadPool, config.contextMode, config.cacheDir, config.localFontFamilyName); BOOL enableCrossSourceCollisions = !config.perSourceCollisions; _rendererFrontend = std::make_unique(std::move(renderer), self, *_mbglView); + + NSAssert(!_mbglMap, @"_mbglMap should be NULL"); _mbglMap = new mbgl::Map(*_rendererFrontend, *_mbglView, self.size, config.scaleFactor, *[config fileSource], *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default, enableCrossSourceCollisions); // start paused if in IB @@ -686,6 +708,26 @@ - (void)reachabilityChanged:(NSNotification *)notification _isWaitingForRedundantReachableNotification = NO; } + +- (void)destroyCoreObjects { + // Record the current state. Currently only saving a limited set of properties. + self.terminated = YES; + self.residualCamera = self.camera; + self.residualDebugMask = self.debugMask; + self.residualStyleURL = self.styleURL; + + // Tear down C++ objects, insuring worker threads correctly terminate. + // Because of how _mbglMap is constructed, we need to destroy it first. + delete _mbglMap; + _mbglMap = nullptr; + + delete _mbglView; + _mbglView = nullptr; + + _rendererFrontend.reset(); + _mbglThreadPool.reset(); +} + - (void)dealloc { MGLLogInfo(@"Deallocating MGLMapView."); @@ -704,17 +746,7 @@ - (void)dealloc [self validateDisplayLink]; - if (_mbglMap) - { - delete _mbglMap; - _mbglMap = nullptr; - } - - if (_mbglView) - { - delete _mbglView; - _mbglView = nullptr; - } + [self destroyCoreObjects]; if ([[EAGLContext currentContext] isEqual:_context]) { @@ -1017,8 +1049,8 @@ - (void)layoutSubviews [self adjustContentInset]; - if (!_isTargetingInterfaceBuilder) { - _mbglMap->setSize([self size]); + if (!_isTargetingInterfaceBuilder && _mbglMap) { + self.mbglMap.setSize([self size]); } if (self.compassView.alpha) @@ -1176,6 +1208,8 @@ - (void)willTerminate self.dormant = YES; [self.glView deleteDrawable]; } + + [self destroyCoreObjects]; } - (void)validateDisplayLink @@ -1183,9 +1217,9 @@ - (void)validateDisplayLink BOOL isVisible = self.superview && self.window; if (isVisible && ! _displayLink) { - if (_mbglMap->getConstrainMode() == mbgl::ConstrainMode::None) + if (_mbglMap && self.mbglMap.getConstrainMode() == mbgl::ConstrainMode::None) { - _mbglMap->setConstrainMode(mbgl::ConstrainMode::HeightOnly); + self.mbglMap.setConstrainMode(mbgl::ConstrainMode::HeightOnly); } _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateFromDisplayLink)]; @@ -1385,7 +1419,7 @@ - (void)touchesBegan:(__unused NSSet *)touches withEvent:(__unused UI return; }; - _mbglMap->setGestureInProgress(false); + self.mbglMap.setGestureInProgress(false); if (self.userTrackingState == MGLUserTrackingStateBegan) { [self setUserTrackingMode:MGLUserTrackingModeNone animated:NO]; @@ -1398,7 +1432,7 @@ - (void)notifyGestureDidBegin { BOOL animated = NO; [self cameraWillChangeAnimated:animated]; - _mbglMap->setGestureInProgress(true); + self.mbglMap.setGestureInProgress(true); _changeDelimiterSuppressionDepth++; } @@ -1407,7 +1441,7 @@ - (void)notifyGestureDidEndWithDrift:(BOOL)drift { MGLAssert(_changeDelimiterSuppressionDepth >= 0, @"Unbalanced change delimiter suppression/unsuppression"); if (_changeDelimiterSuppressionDepth == 0) { - _mbglMap->setGestureInProgress(false); + self.mbglMap.setGestureInProgress(false); } if ( ! drift) { @@ -1463,7 +1497,7 @@ - (void)handlePanGesture:(UIPanGestureRecognizer *)pan if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->moveBy({ delta.x, delta.y }); + self.mbglMap.moveBy({ delta.x, delta.y }); [pan setTranslation:CGPointZero inView:pan.view]; } @@ -1486,7 +1520,7 @@ - (void)handlePanGesture:(UIPanGestureRecognizer *)pan if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->moveBy({ offset.x, offset.y }, MGLDurationFromTimeInterval(self.decelerationRate)); + self.mbglMap.moveBy({ offset.x, offset.y }, MGLDurationFromTimeInterval(self.decelerationRate)); } } @@ -1521,7 +1555,7 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch { [self trackGestureEvent:MMEEventGesturePinchStart forRecognizer:pinch]; - self.scale = powf(2, _mbglMap->getZoom()); + self.scale = powf(2, self.mbglMap.getZoom()); [self notifyGestureDidBegin]; } @@ -1536,7 +1570,7 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + self.mbglMap.setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); // The gesture recognizer only reports the gesture’s current center // point, so use the previous center point to anchor the transition. // If the number of touches has changed, the remembered center point is @@ -1544,7 +1578,7 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch if (self.userTrackingMode == MGLUserTrackingModeNone && pinch.numberOfTouches == _previousPinchNumberOfTouches) { CLLocationCoordinate2D centerCoordinate = _previousPinchCenterCoordinate; - _mbglMap->setLatLng(MGLLatLngFromLocationCoordinate2D(centerCoordinate), + self.mbglMap.setLatLng(MGLLatLngFromLocationCoordinate2D(centerCoordinate), mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); } } @@ -1576,7 +1610,7 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch newScale += scale / (velocity * duration) * 0.1; } - if (newScale <= 0 || log2(newScale) < _mbglMap->getMinZoom()) + if (newScale <= 0 || log2(newScale) < self.mbglMap.getMinZoom()) { velocity = 0; } @@ -1595,7 +1629,7 @@ - (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch { if (drift) { - _mbglMap->setZoom(zoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationFromTimeInterval(duration)); + self.mbglMap.setZoom(zoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationFromTimeInterval(duration)); } } @@ -1622,7 +1656,7 @@ - (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate { [self trackGestureEvent:MMEEventGestureRotateStart forRecognizer:rotate]; - self.angle = MGLRadiansFromDegrees(_mbglMap->getBearing()) * -1; + self.angle = MGLRadiansFromDegrees(self.mbglMap.getBearing()) * -1; if (self.userTrackingMode != MGLUserTrackingModeNone) { @@ -1649,7 +1683,7 @@ - (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + self.mbglMap.setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); } [self cameraIsChanging]; @@ -1684,7 +1718,7 @@ - (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationFromTimeInterval(decelerationRate)); + self.mbglMap.setBearing(newDegrees, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationFromTimeInterval(decelerationRate)); [self notifyGestureDidEndWithDrift:YES]; @@ -1816,7 +1850,7 @@ - (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap [self trackGestureEvent:MMEEventGestureDoubleTap forRecognizer:doubleTap]; mbgl::ScreenCoordinate center(gesturePoint.x, gesturePoint.y); - _mbglMap->setZoom(newZoom, center, MGLDurationFromTimeInterval(MGLAnimationDuration)); + self.mbglMap.setZoom(newZoom, center, MGLDurationFromTimeInterval(MGLAnimationDuration)); __weak MGLMapView *weakSelf = self; @@ -1837,7 +1871,7 @@ - (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap if ( ! self.isZoomEnabled) return; - if (_mbglMap->getZoom() == _mbglMap->getMinZoom()) return; + if (self.mbglMap.getZoom() == self.mbglMap.getMinZoom()) return; [self cancelTransitions]; @@ -1856,7 +1890,7 @@ - (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap [self trackGestureEvent:MMEEventGestureTwoFingerSingleTap forRecognizer:twoFingerTap]; mbgl::ScreenCoordinate center(gesturePoint.x, gesturePoint.y); - _mbglMap->setZoom(newZoom, center, MGLDurationFromTimeInterval(MGLAnimationDuration)); + self.mbglMap.setZoom(newZoom, center, MGLDurationFromTimeInterval(MGLAnimationDuration)); __weak MGLMapView *weakSelf = self; @@ -1879,7 +1913,7 @@ - (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom { [self trackGestureEvent:MMEEventGestureQuickZoom forRecognizer:quickZoom]; - self.scale = powf(2, _mbglMap->getZoom()); + self.scale = powf(2, self.mbglMap.getZoom()); self.quickZoomStart = [quickZoom locationInView:quickZoom.view].y; @@ -1889,9 +1923,9 @@ - (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom { CGFloat distance = [quickZoom locationInView:quickZoom.view].y - self.quickZoomStart; - CGFloat newZoom = MAX(log2f(self.scale) + (distance / 75), _mbglMap->getMinZoom()); + CGFloat newZoom = MAX(log2f(self.scale) + (distance / 75), self.mbglMap.getMinZoom()); - if (_mbglMap->getZoom() == newZoom) return; + if (self.mbglMap.getZoom() == newZoom) return; CGPoint centerPoint = [self anchorPointForGesture:quickZoom]; @@ -1900,7 +1934,7 @@ - (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + self.mbglMap.setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); } [self cameraIsChanging]; @@ -1929,7 +1963,7 @@ - (void)handleTwoFingerDragGesture:(UIPanGestureRecognizer *)twoFingerDrag if (twoFingerDrag.state == UIGestureRecognizerStateBegan || twoFingerDrag.state == UIGestureRecognizerStateChanged) { CGFloat gestureDistance = CGPoint([twoFingerDrag translationInView:twoFingerDrag.view]).y; - CGFloat currentPitch = _mbglMap->getPitch(); + CGFloat currentPitch = self.mbglMap.getPitch(); CGFloat slowdown = 20.0; CGFloat pitchNew = currentPitch - (gestureDistance / slowdown); @@ -1941,7 +1975,7 @@ - (void)handleTwoFingerDragGesture:(UIPanGestureRecognizer *)twoFingerDrag if ([self _shouldChangeFromCamera:oldCamera toCamera:toCamera]) { - _mbglMap->setPitch(pitchNew, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + self.mbglMap.setPitch(pitchNew, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); } [self cameraIsChanging]; @@ -1971,11 +2005,11 @@ - (MGLMapCamera *)cameraByZoomingToZoomLevel:(double)zoom aroundAnchorPoint:(CGP { mbgl::ScreenCoordinate anchor = mbgl::ScreenCoordinate { anchorPoint.x, anchorPoint.y }; mbgl::EdgeInsets padding = mbgl::EdgeInsets(anchor.y, anchor.x, self.size.height - anchor.y, self.size.width - anchor.x); - mbgl::CameraOptions currentCameraOptions = _mbglMap->getCameraOptions(padding); + mbgl::CameraOptions currentCameraOptions = self.mbglMap.getCameraOptions(padding); currentCameraOptions.zoom = mbgl::util::clamp(zoom, self.minimumZoomLevel, self.maximumZoomLevel); currentCameraOptions.anchor = anchor; - MGLCoordinateBounds bounds = MGLCoordinateBoundsFromLatLngBounds(_mbglMap->latLngBoundsForCamera(currentCameraOptions)); + MGLCoordinateBounds bounds = MGLCoordinateBoundsFromLatLngBounds(self.mbglMap.latLngBoundsForCamera(currentCameraOptions)); return [self cameraThatFitsCoordinateBounds:bounds]; } @@ -1983,7 +2017,7 @@ - (MGLMapCamera *)cameraByZoomingToZoomLevel:(double)zoom aroundAnchorPoint:(CGP - (MGLMapCamera *)cameraByRotatingToDirection:(CLLocationDirection)degrees aroundAnchorPoint:(CGPoint)anchorPoint { mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); - mbgl::CameraOptions currentCameraOptions = _mbglMap->getCameraOptions(padding); + mbgl::CameraOptions currentCameraOptions = self.mbglMap.getCameraOptions(padding); MGLMapCamera *camera; @@ -1998,7 +2032,7 @@ - (MGLMapCamera *)cameraByRotatingToDirection:(CLLocationDirection)degrees aroun - (MGLMapCamera *)cameraByTiltingToPitch:(CGFloat)pitch { mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); - mbgl::CameraOptions currentCameraOptions = _mbglMap->getCameraOptions(padding); + mbgl::CameraOptions currentCameraOptions = self.mbglMap.getCameraOptions(padding); MGLMapCamera *camera; @@ -2292,7 +2326,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N NSString *symbolName = annotationImage.styleIconIdentifier; // Update the annotation’s backing geometry to match the annotation model object. Any associated annotation view is also moved by side effect. However, -updateAnnotationViews disables the view’s animation actions, because it can’t distinguish between moves due to the viewport changing and moves due to the annotation’s coordinate changing. - _mbglMap->updateAnnotation(annotationTag, mbgl::SymbolAnnotation { point, symbolName.UTF8String }); + self.mbglMap.updateAnnotation(annotationTag, mbgl::SymbolAnnotation { point, symbolName.UTF8String }); [self updateCalloutView]; } } @@ -2310,7 +2344,7 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N if (annotation == [self annotationWithTag:annotationTag]) { // Update the annotation’s backing geometry to match the annotation model object. - _mbglMap->updateAnnotation(annotationTag, [annotation annotationObjectWithDelegate:self]); + self.mbglMap.updateAnnotation(annotationTag, [annotation annotationObjectWithDelegate:self]); [self updateCalloutView]; } } @@ -2338,7 +2372,13 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N - (MGLMapDebugMaskOptions)debugMask { - mbgl::MapDebugOptions options = _mbglMap->getDebug(); + if (!_mbglMap) + { + NSAssert(self.terminated, @"_mbglMap should only be unavailable during app termination"); + return self.residualDebugMask; + } + + mbgl::MapDebugOptions options = self.mbglMap.getDebug(); MGLMapDebugMaskOptions mask = 0; if (options & mbgl::MapDebugOptions::TileBorders) { @@ -2365,6 +2405,11 @@ - (MGLMapDebugMaskOptions)debugMask - (void)setDebugMask:(MGLMapDebugMaskOptions)debugMask { + if (!_mbglMap) + { + return; + } + mbgl::MapDebugOptions options = mbgl::MapDebugOptions::NoDebug; if (debugMask & MGLMapDebugTileBoundariesMask) { @@ -2386,7 +2431,7 @@ - (void)setDebugMask:(MGLMapDebugMaskOptions)debugMask { options |= mbgl::MapDebugOptions::Overdraw; } - _mbglMap->setDebug(options); + self.mbglMap.setDebug(options); } - (void)resetNorth @@ -2403,7 +2448,7 @@ - (void)resetNorthAnimated:(BOOL)animated - (void)resetPosition { MGLLogInfo(@"Resetting the map to the current style’s default viewport."); - auto camera = _mbglMap->getStyle().getDefaultCamera(); + auto camera = self.mbglMap.getStyle().getDefaultCamera(); CGFloat pitch = *camera.pitch; CLLocationDirection heading = mbgl::util::wrap(*camera.angle, 0., 360.); CLLocationDistance altitude = MGLAltitudeForZoomLevel(*camera.zoom, pitch, 0, self.frame.size); @@ -2977,7 +3022,7 @@ - (void)accessibilityScaleBy:(double)scaleFactor centerPoint = self.userLocationAnnotationViewCenter; } double newZoom = round(self.zoomLevel) + log2(scaleFactor); - _mbglMap->setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); + self.mbglMap.setZoom(newZoom, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }); [self unrotateIfNeededForGesture]; _accessibilityValueAnnouncementIsPending = YES; @@ -3005,7 +3050,7 @@ - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - (CLLocationCoordinate2D)centerCoordinate { mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); - return MGLLocationCoordinate2DFromLatLng(_mbglMap->getLatLng(padding)); + return MGLLocationCoordinate2DFromLatLng(self.mbglMap.getLatLng(padding)); } - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel animated:(BOOL)animated @@ -3048,6 +3093,15 @@ - (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate animated:( - (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate edgePadding:(UIEdgeInsets)insets zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction duration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion { + if (!_mbglMap) + { + if (completion) + { + completion(); + } + return; + } + mbgl::CameraOptions cameraOptions; cameraOptions.center = MGLLatLngFromLocationCoordinate2D(centerCoordinate); cameraOptions.padding = MGLEdgeInsetsFromNSEdgeInsets(insets); @@ -3091,7 +3145,7 @@ - (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate edgePaddin self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic; - _mbglMap->easeTo(cameraOptions, animationOptions); + self.mbglMap.easeTo(cameraOptions, animationOptions); } + (NSSet *)keyPathsForValuesAffectingZoomLevel @@ -3101,7 +3155,7 @@ - (void)_setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate edgePaddin - (double)zoomLevel { - return _mbglMap->getZoom(); + return self.mbglMap.getZoom(); } - (void)setZoomLevel:(double)zoomLevel @@ -3120,31 +3174,31 @@ - (void)setZoomLevel:(double)zoomLevel animated:(BOOL)animated CGFloat duration = animated ? MGLAnimationDuration : 0; - _mbglMap->setZoom(zoomLevel, - MGLEdgeInsetsFromNSEdgeInsets(self.contentInset), - MGLDurationFromTimeInterval(duration)); + self.mbglMap.setZoom(zoomLevel, + MGLEdgeInsetsFromNSEdgeInsets(self.contentInset), + MGLDurationFromTimeInterval(duration)); } - (void)setMinimumZoomLevel:(double)minimumZoomLevel { MGLLogDebug(@"Setting minimumZoomLevel: %f", minimumZoomLevel); - _mbglMap->setMinZoom(minimumZoomLevel); + self.mbglMap.setMinZoom(minimumZoomLevel); } - (double)minimumZoomLevel { - return _mbglMap->getMinZoom(); + return self.mbglMap.getMinZoom(); } - (void)setMaximumZoomLevel:(double)maximumZoomLevel { MGLLogDebug(@"Setting maximumZoomLevel: %f", maximumZoomLevel); - _mbglMap->setMaxZoom(maximumZoomLevel); + self.mbglMap.setMaxZoom(maximumZoomLevel); } - (double)maximumZoomLevel { - return _mbglMap->getMaxZoom(); + return self.mbglMap.getMaxZoom(); } - (MGLCoordinateBounds)visibleCoordinateBounds @@ -3243,6 +3297,15 @@ - (void)setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count: - (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count:(NSUInteger)count edgePadding:(UIEdgeInsets)insets direction:(CLLocationDirection)direction duration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion { + if (!_mbglMap) + { + if (completion) + { + completion(); + } + return; + } + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets); padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); std::vector latLngs; @@ -3252,7 +3315,7 @@ - (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count latLngs.push_back({coordinates[i].latitude, coordinates[i].longitude}); } - mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngs(latLngs, padding); + mbgl::CameraOptions cameraOptions = self.mbglMap.cameraForLatLngs(latLngs, padding); if (direction >= 0) { cameraOptions.angle = direction; @@ -3290,7 +3353,7 @@ - (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic; - _mbglMap->easeTo(cameraOptions, animationOptions); + self.mbglMap.easeTo(cameraOptions, animationOptions); [self didChangeValueForKey:@"visibleCoordinateBounds"]; } @@ -3301,7 +3364,7 @@ - (void)_setVisibleCoordinates:(const CLLocationCoordinate2D *)coordinates count - (CLLocationDirection)direction { - return mbgl::util::wrap(_mbglMap->getBearing(), 0., 360.); + return mbgl::util::wrap(self.mbglMap.getBearing(), 0., 360.); } - (void)setDirection:(CLLocationDirection)direction animated:(BOOL)animated @@ -3319,6 +3382,11 @@ - (void)setDirection:(CLLocationDirection)direction animated:(BOOL)animated - (void)_setDirection:(CLLocationDirection)direction animated:(BOOL)animated { + if (!_mbglMap) + { + return; + } + if (direction == self.direction) return; [self cancelTransitions]; @@ -3328,14 +3396,14 @@ - (void)_setDirection:(CLLocationDirection)direction animated:(BOOL)animated if (self.userTrackingMode == MGLUserTrackingModeNone) { - _mbglMap->setBearing(direction, + self.mbglMap.setBearing(direction, MGLEdgeInsetsFromNSEdgeInsets(self.contentInset), MGLDurationFromTimeInterval(duration)); } else { CGPoint centerPoint = self.userLocationAnnotationViewCenter; - _mbglMap->setBearing(direction, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, + self.mbglMap.setBearing(direction, mbgl::ScreenCoordinate { centerPoint.x, centerPoint.y }, MGLDurationFromTimeInterval(duration)); } } @@ -3358,8 +3426,14 @@ - (void)setDirection:(CLLocationDirection)direction - (MGLMapCamera *)camera { + if (!_mbglMap) + { + NSAssert(self.terminated, @"_mbglMap should only be unavailable during app termination"); + return self.residualCamera; + } + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); - return [self cameraForCameraOptions:_mbglMap->getCameraOptions(padding)]; + return [self cameraForCameraOptions:self.mbglMap.getCameraOptions(padding)]; } - (void)setCamera:(MGLMapCamera *)camera @@ -3387,7 +3461,17 @@ - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration a } - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(UIEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion { + if (!_mbglMap) + { + if (completion) + { + completion(); + } + return; + } + MGLLogDebug(@"Setting camera: %@ duration: %f animationTimingFunction: %@ edgePadding: %@ completionHandler: %@", camera, duration, function, NSStringFromUIEdgeInsets(edgePadding), completion); + mbgl::AnimationOptions animationOptions; if (duration > 0) { @@ -3420,7 +3504,7 @@ - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration a self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic; mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:edgePadding]; - _mbglMap->easeTo(cameraOptions, animationOptions); + self.mbglMap.easeTo(cameraOptions, animationOptions); [self didChangeValueForKey:@"camera"]; } @@ -3444,6 +3528,15 @@ - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration - (void)_flyToCamera:(MGLMapCamera *)camera edgePadding:(UIEdgeInsets)insets withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion { + if (!_mbglMap) + { + if (completion) + { + completion(); + } + return; + } + mbgl::AnimationOptions animationOptions; if (duration >= 0) { @@ -3482,13 +3575,17 @@ - (void)_flyToCamera:(MGLMapCamera *)camera edgePadding:(UIEdgeInsets)insets wit self.cameraChangeReasonBitmask |= MGLCameraChangeReasonProgrammatic; mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:insets]; - _mbglMap->flyTo(cameraOptions, animationOptions); + self.mbglMap.flyTo(cameraOptions, animationOptions); [self didChangeValueForKey:@"camera"]; } - (void)cancelTransitions { + if (!_mbglMap) + { + return; + } self.cameraChangeReasonBitmask |= MGLCameraChangeReasonTransitionCancelled; - _mbglMap->cancelTransitions(); + self.mbglMap.cancelTransitions(); self.cameraChangeReasonBitmask &= ~MGLCameraChangeReasonTransitionCancelled; } @@ -3499,14 +3596,24 @@ - (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds - (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets { + if (!_mbglMap) + { + return nil; + } + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets); padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); - mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding); + mbgl::CameraOptions cameraOptions = self.mbglMap.cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding); return [self cameraForCameraOptions:cameraOptions]; } - (MGLMapCamera *)camera:(MGLMapCamera *)camera fittingCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets { + if (!_mbglMap) + { + return nil; + } + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets); padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); @@ -3514,11 +3621,16 @@ - (MGLMapCamera *)camera:(MGLMapCamera *)camera fittingCoordinateBounds:(MGLCoor CGFloat pitch = camera.pitch < 0 ? currentCamera.pitch : camera.pitch; CLLocationDirection direction = camera.heading < 0 ? currentCamera.heading : camera.heading; - mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding, direction, pitch); + mbgl::CameraOptions cameraOptions = self.mbglMap.cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding, direction, pitch); return [self cameraForCameraOptions:cameraOptions]; } - (MGLMapCamera *)camera:(MGLMapCamera *)camera fittingShape:(MGLShape *)shape edgePadding:(UIEdgeInsets)insets { + if (!_mbglMap) + { + return nil; + } + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets); padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); @@ -3526,26 +3638,36 @@ - (MGLMapCamera *)camera:(MGLMapCamera *)camera fittingShape:(MGLShape *)shape e CGFloat pitch = camera.pitch < 0 ? currentCamera.pitch : camera.pitch; CLLocationDirection direction = camera.heading < 0 ? currentCamera.heading : camera.heading; - mbgl::CameraOptions cameraOptions = _mbglMap->cameraForGeometry([shape geometryObject], padding, direction, pitch); + mbgl::CameraOptions cameraOptions = self.mbglMap.cameraForGeometry([shape geometryObject], padding, direction, pitch); return [self cameraForCameraOptions: cameraOptions]; } - (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(CLLocationDirection)direction edgePadding:(UIEdgeInsets)insets { + if (!_mbglMap) + { + return nil; + } + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets); padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset); - mbgl::CameraOptions cameraOptions = _mbglMap->cameraForGeometry([shape geometryObject], padding, direction); + mbgl::CameraOptions cameraOptions = self.mbglMap.cameraForGeometry([shape geometryObject], padding, direction); return [self cameraForCameraOptions:cameraOptions]; } - (MGLMapCamera *)cameraForCameraOptions:(const mbgl::CameraOptions &)cameraOptions { - CLLocationCoordinate2D centerCoordinate = MGLLocationCoordinate2DFromLatLng(cameraOptions.center ? *cameraOptions.center : _mbglMap->getLatLng()); + if (!_mbglMap) + { + return nil; + } + + CLLocationCoordinate2D centerCoordinate = MGLLocationCoordinate2DFromLatLng(cameraOptions.center ? *cameraOptions.center : self.mbglMap.getLatLng()); double zoomLevel = cameraOptions.zoom ? *cameraOptions.zoom : self.zoomLevel; CLLocationDirection direction = cameraOptions.angle ? mbgl::util::wrap(*cameraOptions.angle, 0., 360.) : self.direction; - CGFloat pitch = cameraOptions.pitch ? *cameraOptions.pitch : _mbglMap->getPitch(); + CGFloat pitch = cameraOptions.pitch ? *cameraOptions.pitch : self.mbglMap.getPitch(); CLLocationDistance altitude = MGLAltitudeForZoomLevel(zoomLevel, pitch, centerCoordinate.latitude, self.frame.size); return [MGLMapCamera cameraLookingAtCenterCoordinate:centerCoordinate altitude:altitude pitch:pitch heading:direction]; } @@ -3583,7 +3705,7 @@ - (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(null - (mbgl::LatLng)convertPoint:(CGPoint)point toLatLngFromView:(nullable UIView *)view { CGPoint convertedPoint = [self convertPoint:point fromView:view]; - return _mbglMap->latLngForPixel(mbgl::ScreenCoordinate(convertedPoint.x, convertedPoint.y)).wrapped(); + return self.mbglMap.latLngForPixel(mbgl::ScreenCoordinate(convertedPoint.x, convertedPoint.y)).wrapped(); } - (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(nullable UIView *)view @@ -3598,7 +3720,7 @@ - (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate toPointToView:(n /// Converts a geographic coordinate to a point in the view’s coordinate system. - (CGPoint)convertLatLng:(mbgl::LatLng)latLng toPointToView:(nullable UIView *)view { - mbgl::ScreenCoordinate pixel = _mbglMap->pixelForLatLng(latLng); + mbgl::ScreenCoordinate pixel = self.mbglMap.pixelForLatLng(latLng); return [self convertPoint:CGPointMake(pixel.x, pixel.y) toView:view]; } @@ -3816,7 +3938,7 @@ - (void)addAnnotations:(NSArray> *)annotations } _isChangingAnnotationLayers = YES; - MGLAnnotationTag annotationTag = _mbglMap->addAnnotation([multiPoint annotationObjectWithDelegate:self]); + MGLAnnotationTag annotationTag = self.mbglMap.addAnnotation([multiPoint annotationObjectWithDelegate:self]); MGLAnnotationContext context; context.annotation = annotation; _annotationContextsByAnnotationTag[annotationTag] = context; @@ -3884,7 +4006,7 @@ - (void)addAnnotations:(NSArray> *)annotations annotationImagesForAnnotation[annotationValue] = annotationImage; } - MGLAnnotationTag annotationTag = _mbglMap->addAnnotation(mbgl::SymbolAnnotation { + MGLAnnotationTag annotationTag = self.mbglMap.addAnnotation(mbgl::SymbolAnnotation { MGLPointFromLocationCoordinate2D(annotation.coordinate), symbolName.UTF8String }); @@ -4063,7 +4185,7 @@ - (void)installAnnotationImage:(MGLAnnotationImage *)annotationImage annotationImage.delegate = self; // add sprite - _mbglMap->addAnnotationImage([annotationImage.image mgl_styleImageWithIdentifier:iconIdentifier]); + self.mbglMap.addAnnotationImage([annotationImage.image mgl_styleImageWithIdentifier:iconIdentifier]); // Create a slop area with a “radius” equal in size to the annotation // image’s alignment rect, allowing the eventual tap to be on any point @@ -4137,7 +4259,7 @@ - (void)removeAnnotations:(NSArray> *)annotations } _isChangingAnnotationLayers = YES; - _mbglMap->removeAnnotation(annotationTag); + self.mbglMap.removeAnnotation(annotationTag); } [self didChangeValueForKey:@"annotations"]; @@ -4889,7 +5011,7 @@ - (void)applyIconIdentifier:(NSString *)iconIdentifier toAnnotationsWithImageReu if ([pair.second.imageReuseIdentifier isEqualToString:reuseIdentifier]) { const mbgl::Point point = MGLPointFromLocationCoordinate2D(pair.second.annotation.coordinate); - _mbglMap->updateAnnotation(pair.first, mbgl::SymbolAnnotation { point, iconIdentifier.UTF8String ?: "" }); + self.mbglMap.updateAnnotation(pair.first, mbgl::SymbolAnnotation { point, iconIdentifier.UTF8String ?: "" }); } } } @@ -5610,7 +5732,7 @@ - (void)animateWithDelay:(NSTimeInterval)delay animations:(void (^)(void))animat - (CGFloat)currentMinimumZoom { - return fmaxf(_mbglMap->getMinZoom(), MGLMinimumZoom); + return fmaxf(self.mbglMap.getMinZoom(), MGLMinimumZoom); } - (BOOL)isRotationAllowed @@ -5670,7 +5792,8 @@ - (void)unrotateIfNeededAnimated:(BOOL)animated } - (void)cameraWillChangeAnimated:(BOOL)animated { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5704,7 +5827,8 @@ - (void)cameraWillChangeAnimated:(BOOL)animated { } - (void)cameraIsChanging { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5722,7 +5846,8 @@ - (void)cameraIsChanging { } - (void)cameraDidChangeAnimated:(BOOL)animated { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5768,7 +5893,8 @@ - (void)announceAccessibilityValue } - (void)mapViewWillStartLoadingMap { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5779,7 +5905,8 @@ - (void)mapViewWillStartLoadingMap { } - (void)mapViewDidFinishLoadingMap { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5794,7 +5921,8 @@ - (void)mapViewDidFinishLoadingMap { } - (void)mapViewDidFailLoadingMapWithError:(NSError *)error { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5805,7 +5933,8 @@ - (void)mapViewDidFailLoadingMapWithError:(NSError *)error { } - (void)mapViewWillStartRenderingFrame { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5816,7 +5945,8 @@ - (void)mapViewWillStartRenderingFrame { } - (void)mapViewDidFinishRenderingFrameFullyRendered:(BOOL)fullyRendered { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5833,7 +5963,8 @@ - (void)mapViewDidFinishRenderingFrameFullyRendered:(BOOL)fullyRendered { } - (void)mapViewWillStartRenderingMap { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5844,7 +5975,8 @@ - (void)mapViewWillStartRenderingMap { } - (void)mapViewDidFinishRenderingMapFullyRendered:(BOOL)fullyRendered { - if (!_mbglMap) { + if (!_mbglMap) + { return; } @@ -5857,11 +5989,12 @@ - (void)mapViewDidFinishRenderingMapFullyRendered:(BOOL)fullyRendered { } - (void)didFinishLoadingStyle { - if (!_mbglMap) { + if (!_mbglMap) + { return; } - self.style = [[MGLStyle alloc] initWithRawStyle:&_mbglMap->getStyle() mapView:self]; + self.style = [[MGLStyle alloc] initWithRawStyle:&self.mbglMap.getStyle() mapView:self]; if ([self.delegate respondsToSelector:@selector(mapView:didFinishLoadingStyle:)]) { [self.delegate mapView:self didFinishLoadingStyle:self.style]; @@ -6200,7 +6333,7 @@ + (UIImage *)resourceImageNamed:(NSString *)imageName - (BOOL)isFullyLoaded { - return _mbglMap->isFullyLoaded(); + return self.mbglMap.isFullyLoaded(); } - (void)prepareForInterfaceBuilder diff --git a/platform/ios/src/MGLMapView_Private.h b/platform/ios/src/MGLMapView_Private.h index 133d17023e0..bddb9b093e3 100644 --- a/platform/ios/src/MGLMapView_Private.h +++ b/platform/ios/src/MGLMapView_Private.h @@ -8,6 +8,9 @@ namespace mbgl { /// Minimum size of an annotation’s accessibility element. FOUNDATION_EXTERN const CGSize MGLAnnotationAccessibilityElementMinimumSize; +/// Indicates that a method (that uses `mbgl::Map`) was called after app termination. +FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const MGLUnderlyingMapUnavailableException; + @interface MGLMapView (Private) /// Currently shown popover representing the selected annotation. @@ -16,8 +19,6 @@ FOUNDATION_EXTERN const CGSize MGLAnnotationAccessibilityElementMinimumSize; /** Triggers another render pass even when it is not necessary. */ - (void)setNeedsGLDisplay; -- (mbgl::Map *)mbglMap; - - (mbgl::Renderer *)renderer; /** Returns whether the map view is currently loading or processing any assets required to render the map */