Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ios14 location permissions #31

Merged
merged 10 commits into from
Feb 23, 2021
31 changes: 31 additions & 0 deletions platform/ios/platform/darwin/src/MGLLocationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,18 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
/**
Specifies the level of location accuracy the Maps SDK has permission to use.

@note If the value of this property is `CLAccuracyAuthorizationFullAccuracy`, you can set the
`MGLLocationManager.desiredAccuracy` property to any value. If the value is `CLAccuracyAuthorizationReducedAccuracy`,
setting `MGLLocationManager.desiredAccuracy` to a value other than` kCLLocationAccuracyReduced` has no effect on
the location information.
*/
- (CLAccuracyAuthorization)accuracyAuthorization API_AVAILABLE(ios(14));
#endif

/**
Specifies the type of user activity associated with the location updates.

Expand All @@ -78,6 +90,17 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)setActivityType:(CLActivityType)activityType;

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
/**
Requests the user's permission to temporarily use location update services
with full accuracy.

@note If the user turned off location accuracy you may use this method to
request full accuracy for a session.
*/
- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey API_AVAILABLE(ios(14));
#endif

@required

/**
Expand Down Expand Up @@ -195,6 +218,14 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (void)locationManager:(id<MGLLocationManager>)manager
didFailWithError:(nonnull NSError *)error;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
/**
Notifies the delegate that the location authorization status has changed.

@param manager The location manager reporting the change.
*/
- (void)locationManagerDidChangeAuthorization:(id<MGLLocationManager>)manager;
#endif

@optional

Expand Down
31 changes: 31 additions & 0 deletions platform/ios/platform/darwin/src/MGLLocationManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,16 @@ - (CLLocationAccuracy)desiredAccuracy {
}

- (CLAuthorizationStatus)authorizationStatus {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
if (@available(iOS 14.0, *)) {
return self.locationManager.authorizationStatus;
} else {
return kCLAuthorizationStatusNotDetermined;
}
#else
return [CLLocationManager authorizationStatus];
petr-pokorny-1 marked this conversation as resolved.
Show resolved Hide resolved
return [CLLocationManager authorizationStatus];
#endif
}

- (void)setActivityType:(CLActivityType)activityType {
Expand All @@ -49,6 +58,23 @@ - (CLActivityType)activityType {
return self.locationManager.activityType;
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
- (CLAccuracyAuthorization)accuracyAuthorization {
if (@available(iOS 14.0, *)) {
return self.locationManager.accuracyAuthorization;
} else {
return CLAccuracyAuthorizationFullAccuracy;
}
}

- (void)requestTemporaryFullAccuracyAuthorizationWithPurposeKey:(NSString *)purposeKey {
if (@available(iOS 14.0, *)) {
[self.locationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKey:purposeKey];
}
}
#endif


- (void)dismissHeadingCalibrationDisplay {
[self.locationManager dismissHeadingCalibrationDisplay];
}
Expand Down Expand Up @@ -113,4 +139,9 @@ - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *
}
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
- (void)locationManagerDidChangeAuthorization:(CLLocationManager *)manager {
[self.delegate locationManagerDidChangeAuthorization:self];
}
#endif
@end
2 changes: 2 additions & 0 deletions platform/ios/platform/darwin/src/MGLStyleValue.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ id MGLJSONObjectFromMBGLValue(const mbgl::Value &value) {
return @(value);
}, [](const int64_t value) {
return @(value);
}, [](const uint64_t value) {
return @(value);
}, [](const double value) {
return @(value);
}, [](const std::string &value) {
Expand Down
2 changes: 2 additions & 0 deletions platform/ios/platform/darwin/src/MGLStyleValue_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ namespace mbgl {
}
}

id MGLJSONObjectFromMBGLValue(const mbgl::Value &value);

NS_INLINE MGLTransition MGLTransitionFromOptions(const mbgl::style::TransitionOptions& options) {
MGLTransition transition;
transition.duration = MGLTimeIntervalFromDuration(options.duration.value_or(mbgl::Duration::zero()));
Expand Down
12 changes: 12 additions & 0 deletions platform/ios/platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT

### Features

* Added `MGLLocationManager.accuracyAuthorization` and `[MGLLocationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKeyproperty:]` to support iOS 14 location accuracy privacy changes. (cherry pick from [#361](https://github.com/mapbox/mapbox-gl-native-ios/pull/361))
* Added `[MGLLocationManager requestTemporaryFullAccuracyAuthorizationWithPurposeKeyproperty:]` to allow developers request just-in-time full-accuracy permissions. (cherry pick from [#361](https://github.com/mapbox/mapbox-gl-native-ios/pull/361))
* Added `[MGLLocationManagerDelegate locationManagerDidChangeAuthorization:]` to let `MGLMapView` know about privacy changes. (cherry pick from [#376](https://github.com/mapbox/mapbox-gl-native-ios/pull/376))
* Added `[MGLMapViewDelegate mapView:didChangeLocationManagerAuthorization:]` to allow developers adjust their apps to privacy settings changes. (cherry pick from [#376](https://github.com/mapbox/mapbox-gl-native-ios/pull/376))
* Added an approximate user location halo when `MGLLocationManager.accuracyAuthorization` is set to `CLAccuracyAuthorizationReducedAccuracy`. (cherry pick from [#381](https://github.com/mapbox/mapbox-gl-native-ios/pull/381))
* The `MGLAccuracyAuthorizationDescription` as element of `NSLocationTemporaryUsageDescriptionDictionary` Info.plist key can now be set to describe why you request accuracy authorization. (cherry pick from [#392](https://github.com/mapbox/mapbox-gl-native-ios/pull/392))
* Added `[MGLMapViewDelegate mapViewStyleForDefaultUserLocationAnnotationView:]` and `MGLUserLocationAnnotationViewStyle` class to allow developers customize the default user location annotation view UI style. (cherry pick from [#403](https://github.com/mapbox/mapbox-gl-native-ios/pull/403))

### Bug Fixes

* Fixed an issue that caused a crash when custom location managers did not implement `MGLLocationManager.accuracyAuthorization`. (cherry pick from [#474](https://github.com/mapbox/mapbox-gl-native-ios/pull/474))

### Other

* mapbox-gl-js submodule has been replaced with maplibre-gl-js
Expand Down
33 changes: 19 additions & 14 deletions platform/ios/platform/ios/app/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>com.mapbox.MapboxGL</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
Expand All @@ -26,12 +26,28 @@
<true/>
<key>NSHumanReadableCopyright</key>
<string>© 2014–2019 Mapbox</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>The map will display your location. If you choose Always, the map may also use your location when it isn’t visible in order to improve OpenStreetMap and Mapbox products.</string>
petr-pokorny-1 marked this conversation as resolved.
Show resolved Hide resolved
<key>NSLocationAlwaysUsageDescription</key>
<string>The map will display your location. The map may also use your location when it isn’t visible in order to improve OpenStreetMap and Mapbox products.</string>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>MGLAccuracyAuthorizationDescription</key>
<string>MapLibre requires your precise location to help you navigate the map.</string>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string>The map will display your location.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>The map will display your location. If you choose Always, the map may also use your location when it isn’t visible in order to improve OpenStreetMap and Mapbox products.</string>
<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemIconFile</key>
<string>settings</string>
<key>UIApplicationShortcutItemTitle</key>
<string>Settings</string>
<key>UIApplicationShortcutItemType</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).settings</string>
</dict>
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand All @@ -53,16 +69,5 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIApplicationShortcutItems</key>
<array>
<dict>
<key>UIApplicationShortcutItemTitle</key>
<string>Settings</string>
<key>UIApplicationShortcutItemType</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER).settings</string>
<key>UIApplicationShortcutItemIconFile</key>
<string>settings</string>
</dict>
</array>
</dict>
</plist>
3 changes: 1 addition & 2 deletions platform/ios/platform/ios/app/MBXOrnamentsViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#import "MBXOrnamentsViewController.h"

@interface MBXOrnamentsViewController ()<MGLMapViewDelegate>
@interface MBXOrnamentsViewController ()

@property (nonatomic) MGLMapView *mapView;
@property (nonatomic) NSTimer *timer;
Expand Down Expand Up @@ -64,7 +64,6 @@ - (void)viewDidLoad {
zoomLevel:16
direction:30
animated:NO];
mapView.delegate = self;
mapView.showsScale = YES;
[self.view addSubview:mapView];

Expand Down
36 changes: 34 additions & 2 deletions platform/ios/platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

#import "MBXFrameTimeGraphView.h"
#import "../src/MGLMapView_Experimental.h"

#import <objc/runtime.h>

static const CLLocationCoordinate2D WorldTourDestinations[] = {
Expand Down Expand Up @@ -213,7 +212,7 @@ @interface MBXViewController () <UITableViewDelegate,
@property (nonatomic) BOOL zoomLevelOrnamentEnabled;
@property (nonatomic) NSMutableArray<UIWindow *> *helperWindows;
@property (nonatomic) NSMutableArray<UIView *> *contentInsetsOverlays;

@property (nonatomic, copy) void (^locationBlock)(void);
@end

@interface MGLMapView (MBXViewController)
Expand Down Expand Up @@ -1952,6 +1951,12 @@ - (IBAction)cycleStyles:(__unused id)sender
}

- (IBAction)locateUser:(id)sender
{
[self nextTrackingMode:sender];
}


- (void)nextTrackingMode:(id)sender
{
MGLUserTrackingMode nextMode;
NSString *nextAccessibilityValue;
Expand Down Expand Up @@ -2333,6 +2338,33 @@ - (void)mapViewDidFinishRenderingFrame:(MGLMapView *)mapView fullyRendered:(BOOL
}
}

- (void)mapView:(nonnull MGLMapView *)mapView didChangeLocationManagerAuthorization:(nonnull id<MGLLocationManager>)manager {
if (@available(iOS 14, *)) {
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
if (manager.authorizationStatus == kCLAuthorizationStatusDenied || manager.accuracyAuthorization == CLAccuracyAuthorizationReducedAccuracy) {
[self alertAccuracyChanges];
}
#endif
}
}

- (void)alertAccuracyChanges {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Mapbox GL works best with your precise location."
petr-pokorny-1 marked this conversation as resolved.
Show resolved Hide resolved
message:@"You'll get turn-by-turn directions."
preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *settingsAction = [UIAlertAction actionWithTitle:@"Turn On in Settings" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
}];

UIAlertAction *defaultAction = [UIAlertAction actionWithTitle:@"Keep Precise Location Off" style:UIAlertActionStyleDefault
handler:nil];

[alert addAction:settingsAction];
[alert addAction:defaultAction];
[self presentViewController:alert animated:YES completion:nil];
}

- (void)saveCurrentMapState:(__unused NSNotification *)notification {

// The following properties can change after the view loads so we need to save their
Expand Down
17 changes: 16 additions & 1 deletion platform/ios/platform/ios/docs/guides/Info.plist Keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,22 @@ Mapbox-hosted vector tiles and styles require an API access token, which you can

As an alternative, you can use `MGLAccountManager.accessToken` to set a token in code. See [our guide](https://www.mapbox.com/help/ios-private-access-token/) for some tips on keeping access tokens in open source code private.

## MGLAccuracyAuthorizationDescription

Set the Mapbox accuracy authorization description string as an element of `NSLocationTemporaryUsageDescriptionDictionary` to be used by the map to request authorization when the `MGLLocationManager.accuracyAuthorization` is set to `CLAccuracyAuthorizationReducedAccuracy`. Requesting accuracy authorization is available for devices running iOS 14.0 and above.

Example:

```xml
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>MGLAccuracyAuthorizationDescription</key>
<string>Mapbox requires your precise location to help you navigate the map.</string>
</dict>
```

Remove `MGLAccuracyAuthorizationDescription` if you want to control when to request for accuracy authorization.

## MGLMapboxAPIBaseURL

Use this key if you need to customize the API base URL used throughout the SDK. If unset, the default Mapbox API is used.
Expand Down Expand Up @@ -47,4 +63,3 @@ At runtime, you can obtain the value of this key using the `MGLOfflineStorage.da
Beginning in version 4.0, the SDK also performs collision detection between style layers based on different sources by default. For the default behavior, omit the `MGLCollisionBehaviorPre4_0` key or set it to NO (`false`).

This property may also be set using `[[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"MGLCollisionBehaviorPre4_0"]`; it will override any value specified in the `Info.plist`.

Loading