summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Guerra Soto <fabian.guerra@mapbox.com>2018-07-20 14:14:43 -0700
committerGitHub <noreply@github.com>2018-07-20 14:14:43 -0700
commit681e0141de63d0d5a545e87c40216163b2d63fc6 (patch)
tree0253e9980ca3c8a75d8f2e04dae8d69f1ef667bd
parentbbccce18c4d064054726f66e0b9b41cebfe314e4 (diff)
downloadqtlocation-mapboxgl-681e0141de63d0d5a545e87c40216163b2d63fc6.tar.gz
[ios] Mapbox's Location Manager new API. (#12013)
* [ios] The new location manager API provides two new protocols MGLLocationManager and MGLLocationManagerDelegate to handle the location cycle and updates respectively. This enables developers to chose the appropriate location provider according to their needs, or transition between outdoors/indoors location updates. It does provide a default implementation based on CLLocationManager.
-rw-r--r--platform/darwin/src/MGLLocationManager.h181
-rw-r--r--platform/darwin/src/MGLLocationManager.m116
-rw-r--r--platform/darwin/src/MGLLocationManager_Private.h5
-rw-r--r--platform/ios/CHANGELOG.md4
-rw-r--r--platform/ios/app/MBXCustomLocationViewController.h5
-rw-r--r--platform/ios/app/MBXCustomLocationViewController.m174
-rw-r--r--platform/ios/app/MBXViewController.m7
-rw-r--r--platform/ios/app/Main.storyboard16
-rw-r--r--platform/ios/app/simple_route.json184
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj28
-rw-r--r--platform/ios/jazzy.yml4
-rw-r--r--platform/ios/src/MGLMapView.h23
-rw-r--r--platform/ios/src/MGLMapView.mm48
-rw-r--r--platform/ios/src/Mapbox.h1
14 files changed, 781 insertions, 15 deletions
diff --git a/platform/darwin/src/MGLLocationManager.h b/platform/darwin/src/MGLLocationManager.h
new file mode 100644
index 0000000000..121dcc2293
--- /dev/null
+++ b/platform/darwin/src/MGLLocationManager.h
@@ -0,0 +1,181 @@
+#import <Foundation/Foundation.h>
+#import <CoreLocation/CoreLocation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@protocol MGLLocationManagerDelegate;
+
+/**
+ The `MGLLocationManager` protocol defines a set of methods that a class must
+ implement in order to serve as the location manager of an `MGLMapView`. A location
+ manager is responsible for notifying the map view about location-related events,
+ such as a change in the user’s location. This protocol is similar to the
+ Core Location framework’s `CLLocationManager` class, but your implementation
+ does not need to be based on `CLLocationManager`.
+
+ */
+@protocol MGLLocationManager <NSObject>
+
+@optional
+
+#pragma mark Configuring Location Update Precision
+
+/**
+ Specifies the minimum distance (measured in meters) a device must move horizontally
+ before a location update is generated.
+
+ The default value of this property is `kCLDistanceFilterNone` when `MGLMapView` uses its
+ default location manager.
+
+ @see `CLLocationManager.distanceFilter`
+ */
+@property(nonatomic, assign) CLLocationDistance distanceFilter;
+
+/**
+ Specifies the accuracy of the location data.
+
+ The default value is `kCLLocationAccuracyBest` when `MGLMapView` uses its
+ default location manager.
+
+ @note Determining a location with greater accuracy requires more time and more power.
+
+ @see `CLLocationManager.desiredAccuracy`
+ */
+@property (nonatomic, assign) CLLocationAccuracy desiredAccuracy;
+
+/**
+ Specifies the type of user activity associated with the location updates.
+
+ The location manager uses this property as a cue to determine when location updates
+ may be automatically paused.
+
+ The default value is `CLActivityTypeOther` when `MGLMapView` uses its
+ default location manager.
+
+ @see `CLLocationManager.activityType`
+ */
+@property (nonatomic, assign) CLActivityType activityType;
+
+@required
+
+/**
+ The delegate to receive location updates.
+
+ Do not set the location manager’s delegate yourself. `MGLMapView` sets this property
+ after the location manager becomes `MGLMapView`’s location manager.
+ */
+@property (nonatomic, weak) id<MGLLocationManagerDelegate> delegate;
+
+#pragma mark Requesting Authorization for Location Services
+
+/**
+ Returns the current localization authorization status.
+
+ @see `+[CLLocationManger authorizationStatus]`
+ */
+@property (nonatomic, readonly) CLAuthorizationStatus authorizationStatus;
+
+/**
+ Requests permission to use the location services whenever the app is running.
+ */
+- (void)requestAlwaysAuthorization;
+
+/**
+ Requests permission to use the location services while the app is in
+ the foreground.
+ */
+- (void)requestWhenInUseAuthorization;
+
+#pragma mark Initiating Location Updates
+
+/**
+ Starts the generation of location updates that reports the user's current location.
+ */
+- (void)startUpdatingLocation;
+
+/**
+ Stops the generation of location updates.
+ */
+- (void)stopUpdatingLocation;
+
+#pragma mark Initiating Heading Updates
+
+/**
+ Specifies a physical device orientation.
+ */
+@property (nonatomic) CLDeviceOrientation headingOrientation;
+
+/**
+ Starts the generation of heading updates that reports the user's current hading.
+ */
+- (void)startUpdatingHeading;
+
+/**
+ Stops the generation of heading updates.
+ */
+- (void)stopUpdatingHeading;
+
+/**
+ Dissmisses immediately the heading calibration view from screen.
+ */
+- (void)dismissHeadingCalibrationDisplay;
+
+@end
+
+/**
+ The `MGLLocationManagerDelegate` protocol defines a set of methods that respond
+ to location updates from an `MGLLocationManager` object that is serving as the
+ location manager of an `MGLMapView`.
+ */
+@protocol MGLLocationManagerDelegate <NSObject>
+
+#pragma mark Responding to Location Updates
+
+/**
+ Notifies the delegate with the new location data.
+
+ @param manager The location manager reporting the update.
+ @param locations An array of `CLLocation` objects in chronological order,
+ with the last object representing the most recent location. This array
+ contains multiple `CLLocation` objects when `MGLMapView` uses its
+ default location manager.
+ */
+- (void)locationManager:(id<MGLLocationManager>)manager
+ didUpdateLocations:(NSArray<CLLocation *> *)locations;
+
+#pragma mark Responding to Heading Updates
+
+/**
+ Notifies the delegate with the new heading data.
+
+ @param manager The location manager reporting the update.
+ @param newHeading The new heading update.
+ */
+- (void)locationManager:(id<MGLLocationManager>)manager
+ didUpdateHeading:(CLHeading *)newHeading;
+
+/**
+ Asks the delegate if the calibration alert should be displayed.
+
+ @param manager The location manager reporting the calibration.
+ */
+- (BOOL)locationManagerShouldDisplayHeadingCalibration:(id<MGLLocationManager>)manager;
+
+#pragma mark Responding to Location Updates Errors
+
+/**
+ Notifies the delegate that the location manager was unable to retrieve
+ location updates.
+
+ @param manager The location manager reporting the error.
+ @param error An error object containing the error code that indicates
+ why the location manager failed.
+ */
+- (void)locationManager:(id<MGLLocationManager>)manager
+ didFailWithError:(nonnull NSError *)error;
+
+@optional
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLLocationManager.m b/platform/darwin/src/MGLLocationManager.m
new file mode 100644
index 0000000000..29e3ccaa30
--- /dev/null
+++ b/platform/darwin/src/MGLLocationManager.m
@@ -0,0 +1,116 @@
+#import "MGLLocationManager_Private.h"
+
+@interface MGLCLLocationManager()<CLLocationManagerDelegate>
+
+@property (nonatomic) CLLocationManager *locationManager;
+
+@end
+
+@implementation MGLCLLocationManager
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ _locationManager = [[CLLocationManager alloc] init];
+ _locationManager.delegate = self;
+ }
+ return self;
+}
+
+@synthesize delegate;
+
+- (void)setHeadingOrientation:(CLDeviceOrientation)headingOrientation
+{
+ self.locationManager.headingOrientation = headingOrientation;
+}
+
+- (CLDeviceOrientation)headingOrientation
+{
+ return self.locationManager.headingOrientation;
+}
+
+- (void)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy {
+ self.locationManager.desiredAccuracy = desiredAccuracy;
+}
+
+- (CLLocationAccuracy)desiredAccuracy {
+ return self.locationManager.desiredAccuracy;
+}
+
+- (CLAuthorizationStatus)authorizationStatus {
+ return [CLLocationManager authorizationStatus];
+}
+
+- (void)setActivityType:(CLActivityType)activityType {
+ self.locationManager.activityType = activityType;
+}
+
+- (CLActivityType)activityType {
+ return self.locationManager.activityType;
+}
+
+- (void)dismissHeadingCalibrationDisplay {
+ [self.locationManager dismissHeadingCalibrationDisplay];
+}
+
+- (void)requestAlwaysAuthorization {
+ [self.locationManager requestAlwaysAuthorization];
+}
+
+- (void)requestWhenInUseAuthorization {
+ [self.locationManager requestWhenInUseAuthorization];
+}
+
+- (void)startUpdatingHeading {
+ [self.locationManager startUpdatingHeading];
+}
+
+- (void)startUpdatingLocation {
+ [self.locationManager startUpdatingLocation];
+}
+
+- (void)stopUpdatingHeading {
+ [self.locationManager stopUpdatingHeading];
+}
+
+- (void)stopUpdatingLocation {
+ [self.locationManager stopUpdatingLocation];
+}
+
+- (void)dealloc
+{
+ [self.locationManager stopUpdatingLocation];
+ [self.locationManager stopUpdatingHeading];
+ self.locationManager.delegate = nil;
+ self.delegate = nil;
+}
+
+#pragma mark - CLLocationManagerDelegate
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
+ if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateLocations:)]) {
+ [self.delegate locationManager:self didUpdateLocations:locations];
+ }
+}
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading {
+ if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateHeading:)]) {
+ [self.delegate locationManager:self didUpdateHeading:newHeading];
+ }
+}
+
+- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager {
+ if ([self.delegate respondsToSelector:@selector(locationManagerShouldDisplayHeadingCalibration:)]) {
+ return [self.delegate locationManagerShouldDisplayHeadingCalibration:self];
+ }
+
+ return NO;
+}
+
+- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
+ if ([self.delegate respondsToSelector:@selector(locationManager:didFailWithError:)]) {
+ [self.delegate locationManager:self didFailWithError:error];
+ }
+}
+
+@end
diff --git a/platform/darwin/src/MGLLocationManager_Private.h b/platform/darwin/src/MGLLocationManager_Private.h
new file mode 100644
index 0000000000..4f09405e71
--- /dev/null
+++ b/platform/darwin/src/MGLLocationManager_Private.h
@@ -0,0 +1,5 @@
+#import "MGLLocationManager.h"
+
+@interface MGLCLLocationManager : NSObject<MGLLocationManager>
+
+@end
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 791b31d0ac..9cc953bd1c 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -4,8 +4,12 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
## master
+### Other changes
+
* Fixed a crash that occurred when the user started a gesture before the drift animation for a previous gesture was complete. ([#12148](https://github.com/mapbox/mapbox-gl-native/pull/12148))
* Token string syntax (`"{token}"`) in `MGLSymbolStyleLayer` `text` and `iconImageName` properties is now correctly converted to the appropriate `NSExpression` equivalent. ([#11659](https://github.com/mapbox/mapbox-gl-native/issues/11659))
+* Added an `MGLMapView.locationManager` property and `MGLLocationManager` protocol for tracking user location using a custom alternative to `CLLocationManager`. ([#12013](https://github.com/mapbox/mapbox-gl-native/pull/12013))
+
## 4.2.0 - July 18, 2018
diff --git a/platform/ios/app/MBXCustomLocationViewController.h b/platform/ios/app/MBXCustomLocationViewController.h
new file mode 100644
index 0000000000..ae6c14fe2c
--- /dev/null
+++ b/platform/ios/app/MBXCustomLocationViewController.h
@@ -0,0 +1,5 @@
+#import <UIKit/UIKit.h>
+
+@interface MBXCustomLocationViewController : UIViewController
+
+@end
diff --git a/platform/ios/app/MBXCustomLocationViewController.m b/platform/ios/app/MBXCustomLocationViewController.m
new file mode 100644
index 0000000000..34887c5736
--- /dev/null
+++ b/platform/ios/app/MBXCustomLocationViewController.m
@@ -0,0 +1,174 @@
+#import "MBXCustomLocationViewController.h"
+
+#import <Mapbox/Mapbox.h>
+
+@interface MBXCustomLocationManager : NSObject<MGLLocationManager>
+@end
+
+@interface MBXCustomLocationManager()
+
+@property (nonatomic) CLLocationManager *locationManager;
+@property (nonatomic, strong) NSTimer *locationUpdateTimer;
+@property (nonatomic) NSUInteger index;
+@property (strong, nonatomic) NSDictionary *routeCoordinates;
+@property (strong, nonatomic) NSArray *coordinates;
+
+@end
+
+@implementation MBXCustomLocationManager
+
+@synthesize delegate;
+
+- (instancetype)init
+{
+ if (self = [super init]) {
+ _locationManager = [[CLLocationManager alloc] init];
+ _index = 0;
+ }
+ return self;
+}
+
+- (CLAuthorizationStatus)authorizationStatus
+{
+ return [CLLocationManager authorizationStatus];
+}
+
+- (void)setHeadingOrientation:(CLDeviceOrientation)headingOrientation
+{
+ _locationManager.headingOrientation = headingOrientation;
+}
+
+- (CLDeviceOrientation)headingOrientation
+{
+ return _locationManager.headingOrientation;
+}
+
+- (void)requestAlwaysAuthorization
+{
+ [self.locationManager requestAlwaysAuthorization];
+}
+
+- (void)requestWhenInUseAuthorization
+{
+ [self.locationManager requestWhenInUseAuthorization];
+}
+
+- (void)startUpdatingHeading
+{
+ [self.locationManager startUpdatingHeading];
+}
+
+- (void)startUpdatingLocation
+{
+ [self loadRouteCoordinates];
+ self.locationUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:0.8
+ target:self
+ selector:@selector(updateLocation)
+ userInfo:nil
+ repeats:YES];
+}
+
+- (void)stopUpdatingHeading
+{
+ [self.locationManager stopUpdatingHeading];
+}
+
+- (void)stopUpdatingLocation
+{
+ [self.locationUpdateTimer invalidate];
+ self.locationUpdateTimer = nil;
+}
+
+- (void)dismissHeadingCalibrationDisplay
+{
+ [self.locationManager dismissHeadingCalibrationDisplay];
+}
+
+- (void)dealloc
+{
+ [self.locationManager stopUpdatingLocation];
+ [self.locationManager stopUpdatingHeading];
+ self.delegate = nil;
+}
+
+#pragma mark - Location Updates
+
+- (void)loadRouteCoordinates
+{
+ NSString *filePath = [[NSBundle bundleForClass:self.class] pathForResource:@"simple_route" ofType:@"json"];
+ NSData *data = [NSData dataWithContentsOfFile:filePath];
+ _routeCoordinates = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
+ _coordinates = [self.routeCoordinates objectForKey:@"coordinates"];
+}
+
+- (void)updateLocation
+{
+ if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateLocations:)]) {
+
+ if (self.index >= [self.coordinates count] ) {
+ self.index = 0;
+ self.coordinates = [[self.coordinates reverseObjectEnumerator] allObjects];
+ }
+ NSArray *loc = self.coordinates[self.index];
+ CLLocationDegrees latitude = [[loc objectAtIndex:1] doubleValue];
+ CLLocationDegrees longitude = [[loc objectAtIndex:0] doubleValue];
+ CLLocation *location = [[CLLocation alloc] initWithLatitude:latitude longitude:longitude];
+ self.index++;
+ [self.delegate locationManager:self didUpdateLocations:@[location]];
+ }
+}
+
+- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
+{
+ if ([self.delegate respondsToSelector:@selector(locationManager:didUpdateHeading:)]) {
+ [self.delegate locationManager:self didUpdateHeading:newHeading];
+ }
+}
+
+- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
+{
+ if ([self.delegate respondsToSelector:@selector(locationManagerShouldDisplayHeadingCalibration:)]) {
+ return [self.delegate locationManagerShouldDisplayHeadingCalibration:self];
+ }
+
+ return NO;
+}
+
+- (void)locationManager:(CLLocationManager *)locationManager didFailWithError:(nonnull NSError *)error {
+ if ([self.delegate respondsToSelector:@selector(locationManager:didFailWithError:)]) {
+ [self.delegate locationManager:self didFailWithError:error];
+ }
+}
+
+@end
+
+@interface MBXCustomLocationViewController ()
+
+@property (strong, nonatomic) MGLMapView *mapView;
+
+@end
+
+@implementation MBXCustomLocationViewController
+
+- (void)viewDidLoad {
+ [super viewDidLoad];
+
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
+
+ self.mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
+ MBXCustomLocationManager *mbxLocationManager = [[MBXCustomLocationManager alloc] init];
+ self.mapView.locationManager = mbxLocationManager;
+ // Set the map’s center coordinate and zoom level.
+ [self.mapView setCenterCoordinate:CLLocationCoordinate2DMake(37.788380, -122.400121)
+ zoomLevel:13
+ animated:NO];
+
+ [self.view addSubview:self.mapView];
+ self.mapView.showsUserLocation = YES;
+}
+
+- (void)viewWillDisappear:(BOOL)animated {
+ self.mapView.showsUserLocation = NO;
+}
+
+@end
diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m
index 167f07d296..71bad66aee 100644
--- a/platform/ios/app/MBXViewController.m
+++ b/platform/ios/app/MBXViewController.m
@@ -98,6 +98,7 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
MBXSettingsMiscellaneousLocalizeLabels,
MBXSettingsMiscellaneousShowSnapshots,
MBXSettingsMiscellaneousShouldLimitCameraChanges,
+ MBXSettingsMiscellaneousShowCustomLocationManager,
MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile,
};
@@ -444,6 +445,7 @@ CLLocationCoordinate2D randomWorldCoordinate() {
[NSString stringWithFormat:@"Show Labels in %@", (_localizingLabels ? @"Default Language" : [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:[self bestLanguageForUser]])],
@"Show Snapshots",
[NSString stringWithFormat:@"%@ Camera Changes", (_shouldLimitCameraChanges ? @"Unlimit" : @"Limit")],
+ @"View Route Simulation",
]];
if (self.debugLoggingEnabled)
@@ -682,6 +684,11 @@ CLLocationCoordinate2D randomWorldCoordinate() {
[self performSegueWithIdentifier:@"ShowSnapshots" sender:nil];
break;
}
+ case MBXSettingsMiscellaneousShowCustomLocationManager:
+ {
+ [self performSegueWithIdentifier:@"ShowCustomLocationManger" sender:nil];
+ break;
+ }
case MBXSettingsMiscellaneousShouldLimitCameraChanges:
{
self.shouldLimitCameraChanges = !self.shouldLimitCameraChanges;
diff --git a/platform/ios/app/Main.storyboard b/platform/ios/app/Main.storyboard
index 72c5cd013f..3e8a0ad02a 100644
--- a/platform/ios/app/Main.storyboard
+++ b/platform/ios/app/Main.storyboard
@@ -107,6 +107,7 @@
<outlet property="hudLabel" destination="58y-pX-YyB" id="aGG-7a-bZR"/>
<outlet property="mapView" destination="kNe-zV-9ha" id="VNR-WO-1q4"/>
<segue destination="zvf-Qd-4Ru" kind="show" identifier="ShowSnapshots" id="hzX-Jp-UJq"/>
+ <segue destination="dgL-Bu-te0" kind="show" identifier="ShowCustomLocationManger" id="kDM-0K-hSf"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="AAd-8J-9UU" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -432,6 +433,21 @@
</objects>
<point key="canvasLocation" x="1365.5999999999999" y="1083.5082458770617"/>
</scene>
+ <!--Custom Location View Controller-->
+ <scene sceneID="TUi-Dc-6uA">
+ <objects>
+ <viewController id="dgL-Bu-te0" customClass="MBXCustomLocationViewController" sceneMemberID="viewController">
+ <view key="view" contentMode="scaleToFill" id="ero-1d-Jm5">
+ <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+ <viewLayoutGuide key="safeArea" id="t2S-ES-YuE"/>
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="RtO-ic-8Nc" userLabel="First Responder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="2073" y="1082"/>
+ </scene>
</scenes>
<resources>
<image name="TrackingLocationOffMask.png" width="23" height="23"/>
diff --git a/platform/ios/app/simple_route.json b/platform/ios/app/simple_route.json
new file mode 100644
index 0000000000..8b910dbdaf
--- /dev/null
+++ b/platform/ios/app/simple_route.json
@@ -0,0 +1,184 @@
+{
+ "coordinates":[
+ [
+ -122.39899,
+ 37.787357
+ ],
+ [
+ -122.398818,
+ 37.78722
+ ],
+ [
+ -122.398794,
+ 37.7872
+ ],
+ [
+ -122.398259,
+ 37.786773
+ ],
+ [
+ -122.398984,
+ 37.786206
+ ],
+ [
+ -122.399053,
+ 37.786151
+ ],
+ [
+ -122.399379,
+ 37.785888
+ ],
+ [
+ -122.399614,
+ 37.785697
+ ],
+ [
+ -122.399884,
+ 37.785478
+ ],
+ [
+ -122.400382,
+ 37.78509
+ ],
+ [
+ -122.400478,
+ 37.785015
+ ],
+ [
+ -122.400599,
+ 37.785111
+ ],
+ [
+ -122.4012,
+ 37.785587
+ ],
+ [
+ -122.401495,
+ 37.785825
+ ],
+ [
+ -122.401705,
+ 37.785993
+ ],
+ [
+ -122.402041,
+ 37.786261
+ ],
+ [
+ -122.402476,
+ 37.786603
+ ],
+ [
+ -122.402573,
+ 37.78668
+ ],
+ [
+ -122.403019,
+ 37.787031
+ ],
+ [
+ -122.403315,
+ 37.78728
+ ],
+ [
+ -122.403358,
+ 37.787324
+ ],
+ [
+ -122.403382,
+ 37.787356
+ ],
+ [
+ -122.403398,
+ 37.787392
+ ],
+ [
+ -122.403405,
+ 37.787425
+ ],
+ [
+ -122.403415,
+ 37.787486
+ ],
+ [
+ -122.403434,
+ 37.787654
+ ],
+ [
+ -122.403436,
+ 37.787676
+ ],
+ [
+ -122.40344,
+ 37.787698
+ ],
+ [
+ -122.403444,
+ 37.787729
+ ],
+ [
+ -122.403464,
+ 37.787825
+ ],
+ [
+ -122.403476,
+ 37.787877
+ ],
+ [
+ -122.403497,
+ 37.787965
+ ],
+ [
+ -122.403591,
+ 37.788436
+ ],
+ [
+ -122.403684,
+ 37.788901
+ ],
+ [
+ -122.403774,
+ 37.789349
+ ],
+ [
+ -122.403798,
+ 37.789469
+ ],
+ [
+ -122.403872,
+ 37.789833
+ ],
+ [
+ -122.404232,
+ 37.789788
+ ],
+ [
+ -122.405435,
+ 37.789635
+ ],
+ [
+ -122.406,
+ 37.789562
+ ],
+ [
+ -122.406982,
+ 37.789436
+ ],
+ [
+ -122.407475,
+ 37.789373
+ ],
+ [
+ -122.408599,
+ 37.789231
+ ],
+ [
+ -122.408616,
+ 37.789229
+ ],
+ [
+ -122.408451,
+ 37.788454
+ ]
+ ]
+} \ No newline at end of file
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 41b6881dbe..2a9c9b5761 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -30,6 +30,8 @@
1753ED431E53CE6F00A9FD90 /* MGLConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 1753ED411E53CE6F00A9FD90 /* MGLConversion.h */; };
1F06668A1EC64F8E001C16D7 /* MGLLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0666881EC64F8E001C16D7 /* MGLLight.h */; settings = {ATTRIBUTES = (Public, ); }; };
1F06668D1EC64F8E001C16D7 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F0666891EC64F8E001C16D7 /* MGLLight.mm */; };
+ 1F26B6C120E189C9007BCC21 /* MBXCustomLocationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F26B6C020E189C9007BCC21 /* MBXCustomLocationViewController.m */; };
+ 1F26B6C320E1A351007BCC21 /* simple_route.json in Resources */ = {isa = PBXBuildFile; fileRef = 1F26B6C220E1A351007BCC21 /* simple_route.json */; };
1F7454921ECBB42C00021D39 /* MGLLight.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F0666891EC64F8E001C16D7 /* MGLLight.mm */; };
1F7454931ECBB43F00021D39 /* MGLLight.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F0666881EC64F8E001C16D7 /* MGLLight.h */; settings = {ATTRIBUTES = (Public, ); }; };
1F7454961ECD450D00021D39 /* MGLLight_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F7454941ECD450D00021D39 /* MGLLight_Private.h */; };
@@ -38,6 +40,12 @@
1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */; };
1FC4817D2098CBC0000D09B4 /* NSPredicate+MGLPrivateAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FC4817B2098CBC0000D09B4 /* NSPredicate+MGLPrivateAdditions.h */; };
1FC4817F2098CD80000D09B4 /* NSPredicate+MGLPrivateAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FC4817B2098CBC0000D09B4 /* NSPredicate+MGLPrivateAdditions.h */; };
+ 1FCAE2A220B872A400C577DD /* MGLLocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCAE2A020B872A400C577DD /* MGLLocationManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 1FCAE2A320B872A400C577DD /* MGLLocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCAE2A020B872A400C577DD /* MGLLocationManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 1FCAE2A420B872A400C577DD /* MGLLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FCAE2A120B872A400C577DD /* MGLLocationManager.m */; };
+ 1FCAE2A520B872A400C577DD /* MGLLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FCAE2A120B872A400C577DD /* MGLLocationManager.m */; };
+ 1FCAE2A820B88B3800C577DD /* MGLLocationManager_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCAE2A620B88B3800C577DD /* MGLLocationManager_Private.h */; };
+ 1FCAE2A920B88B3800C577DD /* MGLLocationManager_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCAE2A620B88B3800C577DD /* MGLLocationManager_Private.h */; };
30E578171DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; };
30E578181DAA85520050F07E /* UIImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578111DAA7D690050F07E /* UIImage+MGLAdditions.h */; };
30E578191DAA855E0050F07E /* UIImage+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 30E578121DAA7D690050F07E /* UIImage+MGLAdditions.mm */; };
@@ -752,10 +760,16 @@
1753ED411E53CE6F00A9FD90 /* MGLConversion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLConversion.h; sourceTree = "<group>"; };
1F0666881EC64F8E001C16D7 /* MGLLight.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight.h; sourceTree = "<group>"; };
1F0666891EC64F8E001C16D7 /* MGLLight.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLight.mm; sourceTree = "<group>"; };
+ 1F26B6BF20E189C9007BCC21 /* MBXCustomLocationViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MBXCustomLocationViewController.h; sourceTree = "<group>"; };
+ 1F26B6C020E189C9007BCC21 /* MBXCustomLocationViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MBXCustomLocationViewController.m; sourceTree = "<group>"; };
+ 1F26B6C220E1A351007BCC21 /* simple_route.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = simple_route.json; sourceTree = "<group>"; };
1F7454941ECD450D00021D39 /* MGLLight_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLLight_Private.h; sourceTree = "<group>"; };
1F7454A61ED08AB400021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLLightTest.mm; path = ../../darwin/test/MGLLightTest.mm; sourceTree = "<group>"; };
1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = "<group>"; };
1FC4817B2098CBC0000D09B4 /* NSPredicate+MGLPrivateAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSPredicate+MGLPrivateAdditions.h"; sourceTree = "<group>"; };
+ 1FCAE2A020B872A400C577DD /* MGLLocationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLLocationManager.h; sourceTree = "<group>"; };
+ 1FCAE2A120B872A400C577DD /* MGLLocationManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLLocationManager.m; sourceTree = "<group>"; };
+ 1FCAE2A620B88B3800C577DD /* MGLLocationManager_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLLocationManager_Private.h; sourceTree = "<group>"; };
20DABE861DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Foundation.strings"; sourceTree = "<group>"; };
20DABE881DF78148007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = "<group>"; };
20DABE8A1DF78149007AC5FF /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Root.strings"; sourceTree = "<group>"; };
@@ -1697,6 +1711,7 @@
353BAEF51D646370009A8DA9 /* amsterdam.geojson */,
DA1DC96C1CB6C6CE006E619F /* points.geojson */,
DA1DC96D1CB6C6CE006E619F /* polyline.geojson */,
+ 1F26B6C220E1A351007BCC21 /* simple_route.json */,
DA1DC96F1CB6C6CE006E619F /* threestates.geojson */,
DD4823721D94AE6C00EB71B7 /* fill_filter_style.json */,
DD4823731D94AE6C00EB71B7 /* line_filter_style.json */,
@@ -1770,6 +1785,8 @@
DA1DC9691CB6C6B7006E619F /* MBXOfflinePacksTableViewController.m */,
927FBCFA1F4DAA8300F8BF1F /* MBXSnapshotsViewController.h */,
927FBCFB1F4DAA8300F8BF1F /* MBXSnapshotsViewController.m */,
+ 1F26B6BF20E189C9007BCC21 /* MBXCustomLocationViewController.h */,
+ 1F26B6C020E189C9007BCC21 /* MBXCustomLocationViewController.m */,
DA1DC9531CB6C1C2006E619F /* MBXViewController.h */,
DA1DC99A1CB6E064006E619F /* MBXViewController.m */,
632281DD1E6F855900D75A5D /* MBXEmbeddedMapViewController.h */,
@@ -1911,6 +1928,9 @@
DA8847EE1CBAFA5100AB86E3 /* MGLTypes.h */,
DA8848111CBAFA6200AB86E3 /* MGLTypes.m */,
35E1A4D71D74336F007AA97F /* MGLValueEvaluator.h */,
+ 1FCAE2A020B872A400C577DD /* MGLLocationManager.h */,
+ 1FCAE2A620B88B3800C577DD /* MGLLocationManager_Private.h */,
+ 1FCAE2A120B872A400C577DD /* MGLLocationManager.m */,
);
name = Foundation;
path = ../darwin/src;
@@ -2227,6 +2247,7 @@
35E79F201D41266300957B9E /* MGLStyleLayer_Private.h in Headers */,
FA68F14A1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.h in Headers */,
353933FB1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */,
+ 1FCAE2A820B88B3800C577DD /* MGLLocationManager_Private.h in Headers */,
DA8847EF1CBAFA5100AB86E3 /* MGLAccountManager.h in Headers */,
DA35A2C91CCAAAD200E826B2 /* NSValue+MGLAdditions.h in Headers */,
3510FFEA1D6D9C7A00F413B2 /* NSComparisonPredicate+MGLAdditions.h in Headers */,
@@ -2237,6 +2258,7 @@
35D3A1E61E9BE7EB002B38EE /* MGLScaleBar.h in Headers */,
0778DD431F67556700A73B34 /* MGLComputedShapeSource.h in Headers */,
DA8848311CBAFA6200AB86E3 /* NSString+MGLAdditions.h in Headers */,
+ 1FCAE2A220B872A400C577DD /* MGLLocationManager.h in Headers */,
DACA86262019218600E9693A /* MGLRasterDEMSource.h in Headers */,
353933F81D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */,
92F2C3ED1F0E3C3A00268EC0 /* MGLRendererFrontend.h in Headers */,
@@ -2377,6 +2399,7 @@
DA72620C1DEEE3480043BB89 /* MGLOpenGLStyleLayer.h in Headers */,
35CE61831D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */,
96E516F32000597100A02306 /* NSDictionary+MGLAdditions.h in Headers */,
+ 1FCAE2A920B88B3800C577DD /* MGLLocationManager_Private.h in Headers */,
96E516F02000595800A02306 /* NSBundle+MGLAdditions.h in Headers */,
96E516F920005A3500A02306 /* MGLFaux3DUserLocationAnnotationView.h in Headers */,
96E516F22000596D00A02306 /* NSException+MGLAdditions.h in Headers */,
@@ -2416,6 +2439,7 @@
968F36B51E4D128D003A5522 /* MGLDistanceFormatter.h in Headers */,
4018B1CB1CDC288E00F666AF /* MGLAnnotationView.h in Headers */,
DABFB85F1CBE99E500D62B32 /* MGLGeometry.h in Headers */,
+ 1FCAE2A320B872A400C577DD /* MGLLocationManager.h in Headers */,
96E516E02000550C00A02306 /* MGLFeature_Private.h in Headers */,
353933F61D3FB785003F57D7 /* MGLBackgroundStyleLayer.h in Headers */,
DABFB85D1CBE99E500D62B32 /* MGLAccountManager.h in Headers */,
@@ -2736,6 +2760,7 @@
DA1DC9731CB6C6CE006E619F /* threestates.geojson in Resources */,
DA821D061CCC6D59007508D4 /* LaunchScreen.storyboard in Resources */,
96E027231E57C76E004B8E66 /* Localizable.strings in Resources */,
+ 1F26B6C320E1A351007BCC21 /* simple_route.json in Resources */,
DD4823751D94AE6C00EB71B7 /* fill_filter_style.json in Resources */,
DA1DC99F1CB6E088006E619F /* Assets.xcassets in Resources */,
);
@@ -2836,6 +2861,7 @@
927FBCFC1F4DAA8300F8BF1F /* MBXSnapshotsViewController.m in Sources */,
DA1DC99B1CB6E064006E619F /* MBXViewController.m in Sources */,
40FDA76B1CCAAA6800442548 /* MBXAnnotationView.m in Sources */,
+ 1F26B6C120E189C9007BCC21 /* MBXCustomLocationViewController.m in Sources */,
3E6465D62065767A00685536 /* LimeGreenStyleLayer.m in Sources */,
632281DF1E6F855900D75A5D /* MBXEmbeddedMapViewController.m in Sources */,
);
@@ -3000,6 +3026,7 @@
40834BED1FE05E1800C1BD0D /* MMEEventLogger.m in Sources */,
353AFA161D65AB17005A69F4 /* NSDate+MGLAdditions.mm in Sources */,
40834BF41FE05E1800C1BD0D /* MMETrustKitWrapper.m in Sources */,
+ 1FCAE2A420B872A400C577DD /* MGLLocationManager.m in Sources */,
40834BEF1FE05E1800C1BD0D /* MMEEventsManager.m in Sources */,
35D13AC51D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm in Sources */,
DA8848241CBAFA6200AB86E3 /* MGLOfflineStorage.mm in Sources */,
@@ -3126,6 +3153,7 @@
40834C011FE05E1800C1BD0D /* MMEEventLogger.m in Sources */,
35D13AC61D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm in Sources */,
40834C081FE05E1800C1BD0D /* MMETrustKitWrapper.m in Sources */,
+ 1FCAE2A520B872A400C577DD /* MGLLocationManager.m in Sources */,
40834C031FE05E1800C1BD0D /* MMEEventsManager.m in Sources */,
DAA4E42A1CBB730400178DFB /* NSProcessInfo+MGLAdditions.m in Sources */,
DAA4E4211CBB730400178DFB /* MGLOfflineStorage.mm in Sources */,
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index d3aae51b77..f995cc06cd 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -60,6 +60,10 @@ custom_categories:
children:
- MGLCalloutView
- MGLCalloutViewDelegate
+ - name: Location Updates
+ children:
+ - MGLLocationManager
+ - MGLLocationManagerDelegate
- name: Styling the Map
children:
- MGLStyle
diff --git a/platform/ios/src/MGLMapView.h b/platform/ios/src/MGLMapView.h
index 04a7a06313..b2439416ae 100644
--- a/platform/ios/src/MGLMapView.h
+++ b/platform/ios/src/MGLMapView.h
@@ -2,7 +2,6 @@
#import "MGLMapCamera.h"
#import <UIKit/UIKit.h>
-#import <CoreLocation/CoreLocation.h>
#import "MGLFoundation.h"
#import "MGLTypes.h"
@@ -22,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
@protocol MGLOverlay;
@protocol MGLCalloutView;
@protocol MGLFeature;
+@protocol MGLLocationManager;
/** The default deceleration rate for a map view. */
extern MGL_EXPORT const CGFloat MGLMapViewDecelerationRateNormal;
@@ -297,6 +297,24 @@ MGL_EXPORT IB_DESIGNABLE
#pragma mark Displaying the User’s Location
/**
+ The object that this map view uses to start and stop the delivery of location-related
+ updates.
+
+ To receive the current user location, implement the `-[MGLMapViewDelegate mapView:didUpdateUserLocation:]`
+ and `-[MGLMapViewDelegate mapView:didFailToLocateUserWithError:]` methods.
+
+ If setting this property to `nil` and setting `showsUserLocation` to `YES`, or
+ if no custom manager is provided this property is set to the default
+ location manager.
+
+ `MGLMapView` uses a default location manager. If you want to substitute your own
+ location manager, you should do so by setting this property before setting
+ `showsUserLocation` to `YES`. To restore the default location manager,
+ set this property to `nil`.
+ */
+@property (nonatomic, null_resettable) id<MGLLocationManager> locationManager;
+
+/**
A Boolean value indicating whether the map may display the user location.
Setting this property to `YES` causes the map view to use the Core Location
@@ -312,6 +330,9 @@ MGL_EXPORT IB_DESIGNABLE
`NSLocationAlwaysUsageDescription` in its `Info.plist` to satisfy the
requirements of the underlying Core Location framework when enabling this
property.
+
+ If you implement a custom location manager, set the `locationManager` before
+ calling `showsUserLocation`.
*/
@property (nonatomic, assign) BOOL showsUserLocation;
diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm
index e4906e3688..cdacfb462b 100644
--- a/platform/ios/src/MGLMapView.mm
+++ b/platform/ios/src/MGLMapView.mm
@@ -73,6 +73,7 @@
#import "MGLAnnotationContainerView_Private.h"
#import "MGLAttributionInfo_Private.h"
#import "MGLMapAccessibilityElement.h"
+#import "MGLLocationManager_Private.h"
#include <algorithm>
#include <cstdlib>
@@ -184,7 +185,7 @@ public:
@interface MGLMapView () <UIGestureRecognizerDelegate,
GLKViewDelegate,
- CLLocationManagerDelegate,
+ MGLLocationManagerDelegate,
MGLSMCalloutViewDelegate,
MGLCalloutViewDelegate,
MGLMultiPointDelegate,
@@ -225,7 +226,6 @@ public:
/// Indicates how thoroughly the map view is tracking the user location.
@property (nonatomic) MGLUserTrackingState userTrackingState;
-@property (nonatomic) CLLocationManager *locationManager;
@property (nonatomic) CGFloat scale;
@property (nonatomic) CGFloat angle;
@property (nonatomic) CGFloat quickZoomStart;
@@ -694,6 +694,9 @@ public:
[self.attributionButtonConstraints removeAllObjects];
self.attributionButtonConstraints = nil;
+
+ self.locationManager.delegate = nil;
+ self.locationManager = nil;
}
- (void)setDelegate:(nullable id<MGLMapViewDelegate>)delegate
@@ -4687,15 +4690,29 @@ public:
#pragma mark - User Location -
+- (void)setLocationManager:(id<MGLLocationManager>)locationManager
+{
+ if (!locationManager) {
+ [self.locationManager stopUpdatingLocation];
+ [self.locationManager stopUpdatingHeading];
+ }
+ self.locationManager.delegate = nil;
+ _locationManager = locationManager;
+ _locationManager.delegate = self;
+}
+
- (void)validateLocationServices
{
BOOL shouldEnableLocationServices = self.showsUserLocation && !self.dormant;
- if (shouldEnableLocationServices && ! self.locationManager)
+ if (shouldEnableLocationServices)
{
- self.locationManager = [[CLLocationManager alloc] init];
+ // If no custom location manager is provided will use the internal implementation.
+ if (!self.locationManager) {
+ self.locationManager = [[MGLCLLocationManager alloc] init];
+ }
- if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined)
+ if (self.locationManager.authorizationStatus == kCLAuthorizationStatusNotDetermined)
{
BOOL requiresWhenInUseUsageDescription = [NSProcessInfo.processInfo isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){11,0,0}];
BOOL hasWhenInUseUsageDescription = !![[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSLocationWhenInUseUsageDescription"];
@@ -4735,8 +4752,6 @@ public:
{
[self.locationManager stopUpdatingLocation];
[self.locationManager stopUpdatingHeading];
- self.locationManager.delegate = nil;
- self.locationManager = nil;
}
}
@@ -4966,12 +4981,12 @@ public:
}
}
-- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
+- (void)locationManager:(id<MGLLocationManager>)manager didUpdateLocations:(NSArray *)locations
{
[self locationManager:manager didUpdateLocations:locations animated:YES];
}
-- (void)locationManager:(__unused CLLocationManager *)manager didUpdateLocations:(NSArray *)locations animated:(BOOL)animated
+- (void)locationManager:(__unused id<MGLLocationManager>)manager didUpdateLocations:(NSArray *)locations animated:(BOOL)animated
{
CLLocation *oldLocation = self.userLocation.location;
CLLocation *newLocation = locations.lastObject;
@@ -5198,16 +5213,21 @@ public:
return direction;
}
-- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager
+- (BOOL)locationManagerShouldDisplayHeadingCalibration:(id<MGLLocationManager>)manager
{
- if (self.displayHeadingCalibration) [manager performSelector:@selector(dismissHeadingCalibrationDisplay)
- withObject:nil
+ if (self.displayHeadingCalibration) [self performSelector:@selector(dismissHeadingCalibrationDisplay:)
+ withObject:manager
afterDelay:10.0];
return self.displayHeadingCalibration;
}
-- (void)locationManager:(__unused CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading
+- (void)dismissHeadingCalibrationDisplay:(id<MGLLocationManager>)manager
+{
+ [manager dismissHeadingCalibrationDisplay];
+}
+
+- (void)locationManager:(__unused id<MGLLocationManager>)manager didUpdateHeading:(CLHeading *)newHeading
{
if ( ! _showsUserLocation || self.pan.state == UIGestureRecognizerStateBegan || newHeading.headingAccuracy < 0) return;
@@ -5234,7 +5254,7 @@ public:
}
}
-- (void)locationManager:(__unused CLLocationManager *)manager didFailWithError:(NSError *)error
+- (void)locationManager:(__unused id<MGLLocationManager>)manager didFailWithError:(NSError *)error
{
if ([error code] == kCLErrorDenied)
{
diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h
index 7beb8b766b..a0afe2d9cc 100644
--- a/platform/ios/src/Mapbox.h
+++ b/platform/ios/src/Mapbox.h
@@ -67,3 +67,4 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "MGLMapSnapshotter.h"
#import "NSExpression+MGLAdditions.h"
#import "NSPredicate+MGLAdditions.h"
+#import "MGLLocationManager.h"