Permalink
Browse files

iOS: Geolocation: Allow skipping of permission prompts

Summary:
This change enables developers to tell the Geolocation module to skip its permissions requests so the app can manage the permissions requests on its own. React Native Android's Geolocation module already requires apps to request permissions on their own.

Currently, the Geolocation module automatically makes permissions requests for you based on what you've specified in your property list file. However, the property list file doesn't always represent what permissions the app wants right now. For example, suppose an app sometimes wants location when "in use" and sometimes wants location "always" depending on what app features the user has engaged with. The Geolocation API will request the "always" location permission even if that's not what the app wants for the current scenario.

This change enables developers to tell the Geolocation module to skip permission requests so that the app can explicitly ask for the appropriate permissions. By default, Geolocation will still ask for permissions so this is not a breaking change.

This change adds a method to Geolocation that is not supported by the web spec for geolocation (`setRNConfiguration`). This method includes `RN` in the name to minimize the chances that the web spec will introduce an API with the same name.

**Test plan (required)**

Verified that Geolocation requests permissions by default and when `skipPermissionRequests` is `false`. Verified the permission requests are skipped when `skipPermissionRequests` is `true`. Also, my team is using this change in our app.

Adam Comella
Microsoft Corp.
Closes #15096

Differential Revision: D5725563

Pulled By: javache

fbshipit-source-id: fd23fedb7e57408fa0f0d0568e0f1ef2aea1cdd4
  • Loading branch information...
rigdern authored and facebook-github-bot committed Aug 29, 2017
1 parent 46f0a3b commit 6b7f10d43e263ac7d73275d37d3be6a40262c3d7
Showing with 45 additions and 1 deletion.
  1. +23 −0 Libraries/Geolocation/Geolocation.js
  2. +22 −1 Libraries/Geolocation/RCTLocationObserver.m
@@ -26,6 +26,10 @@ const PermissionsAndroid = require('PermissionsAndroid');
var subscriptions = [];
var updatesEnabled = false;

type GeoConfiguration = {
skipPermissionRequests: bool;
}

type GeoOptions = {
timeout?: number,
maximumAge?: number,
@@ -75,6 +79,25 @@ type GeoOptions = {
*/
var Geolocation = {

/*
* Sets configuration options that will be used in all location requests.
*
* ### Options
*
* #### iOS
*
* - `skipPermissionRequests` - defaults to `false`, if `true` you must request permissions
* before using Geolocation APIs.
*
*/
setRNConfiguration: function(
config: GeoConfiguration
) {
if (RCTLocationObserver.setConfiguration) {
RCTLocationObserver.setConfiguration(config);
}
},

/*
* Request suitable Location permission based on the key configured on pList.
* If NSLocationAlwaysUsageDescription is set, it will request Always authorization,
@@ -27,6 +27,10 @@ typedef NS_ENUM(NSInteger, RCTPositionErrorCode) {

#define RCT_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyHundredMeters

typedef struct {
BOOL skipPermissionRequests;
} RCTLocationConfiguration;

typedef struct {
double timeout;
double maximumAge;
@@ -37,6 +41,15 @@ typedef NS_ENUM(NSInteger, RCTPositionErrorCode) {

@implementation RCTConvert (RCTLocationOptions)

+ (RCTLocationConfiguration)RCTLocationConfiguration:(id)json
{
NSDictionary<NSString *, id> *options = [RCTConvert NSDictionary:json];

return (RCTLocationConfiguration) {
.skipPermissionRequests = [RCTConvert BOOL:options[@"skipPermissionRequests"]]
};
}

+ (RCTLocationOptions)RCTLocationOptions:(id)json
{
NSDictionary<NSString *, id> *options = [RCTConvert NSDictionary:json];
@@ -111,6 +124,7 @@ @implementation RCTLocationObserver
NSMutableArray<RCTLocationRequest *> *_pendingRequests;
BOOL _observingLocation;
BOOL _usingSignificantChanges;
RCTLocationConfiguration _locationConfiguration;
RCTLocationOptions _observerOptions;
}

@@ -141,7 +155,9 @@ - (dispatch_queue_t)methodQueue

- (void)beginLocationUpdatesWithDesiredAccuracy:(CLLocationAccuracy)desiredAccuracy distanceFilter:(CLLocationDistance)distanceFilter useSignificantChanges:(BOOL)useSignificantChanges
{
[self requestAuthorization];
if (!_locationConfiguration.skipPermissionRequests) {
[self requestAuthorization];
}

_locationManager.distanceFilter = distanceFilter;
_locationManager.desiredAccuracy = desiredAccuracy;
@@ -172,6 +188,11 @@ - (void)timeout:(NSTimer *)timer

#pragma mark - Public API

RCT_EXPORT_METHOD(setConfiguration:(RCTLocationConfiguration)config)
{
_locationConfiguration = config;
}

RCT_EXPORT_METHOD(requestAuthorization)
{
if (!_locationManager) {

0 comments on commit 6b7f10d

Please sign in to comment.