Expose option for distance filtering on location updates.

Summary:
My original implementation involved creating a `RCT_ENUM_CONVERTER` with `CLLocationAccuracy` on iOS and a Hashmap on Android that would convert `string` values to `doubles` for distance filtering.

I got this to work just fine but realized that I made things more complicated than they needed to be and simplified everything by just have the option be a decimal value (in meters) that works both for iOS and Android.

The only thing i'm not sure about is if we can set arbitrary values for CLLocationManager's distance filter.
nicklockwood  Any idea?
Closes https://github.com/facebook/react-native/pull/5563

Reviewed By: svcscm

Differential Revision: D2908250

Pulled By: nicklockwood

fb-gh-sync-id: d83c12b3ce7c343f413749a2cd614b3bf04d6750
This commit is contained in:
Christopher Dro 2016-02-05 16:54:14 -08:00 committed by facebook-github-bot-3
parent 52755fdde2
commit 109036b4c4
3 changed files with 18 additions and 6 deletions

View File

@ -26,6 +26,7 @@ type GeoOptions = {
timeout: number;
maximumAge: number;
enableHighAccuracy: bool;
distanceFilter: number;
}
/**
@ -68,7 +69,7 @@ var Geolocation = {
/*
* Invokes the success callback whenever the location changes. Supported
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool), distanceFilter(m)
*/
watchPosition: function(success: Function, error?: Function, options?: GeoOptions): number {
if (!updatesEnabled) {

View File

@ -31,6 +31,7 @@ typedef struct {
double timeout;
double maximumAge;
double accuracy;
double distanceFilter;
} RCTLocationOptions;
@implementation RCTConvert (RCTLocationOptions)
@ -38,10 +39,15 @@ typedef struct {
+ (RCTLocationOptions)RCTLocationOptions:(id)json
{
NSDictionary<NSString *, id> *options = [RCTConvert NSDictionary:json];
double distanceFilter = options[@"distanceFilter"] == NULL ? RCT_DEFAULT_LOCATION_ACCURACY
: [RCTConvert double:options[@"distanceFilter"]] ?: kCLDistanceFilterNone;
return (RCTLocationOptions){
.timeout = [RCTConvert NSTimeInterval:options[@"timeout"]] ?: INFINITY,
.maximumAge = [RCTConvert NSTimeInterval:options[@"maximumAge"]] ?: INFINITY,
.accuracy = [RCTConvert BOOL:options[@"enableHighAccuracy"]] ? kCLLocationAccuracyBest : RCT_DEFAULT_LOCATION_ACCURACY
.accuracy = [RCTConvert BOOL:options[@"enableHighAccuracy"]] ? kCLLocationAccuracyBest : RCT_DEFAULT_LOCATION_ACCURACY,
.distanceFilter = distanceFilter
};
}
@ -128,7 +134,7 @@ RCT_EXPORT_MODULE()
{
if (!_locationManager) {
_locationManager = [CLLocationManager new];
_locationManager.distanceFilter = RCT_DEFAULT_LOCATION_ACCURACY;
_locationManager.distanceFilter = _observerOptions.distanceFilter;
_locationManager.delegate = self;
}

View File

@ -36,6 +36,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEm
public class LocationModule extends ReactContextBaseJavaModule {
private @Nullable String mWatchedProvider;
private static final float RCT_DEFAULT_LOCATION_ACCURACY = 100;
private final LocationListener mLocationListener = new LocationListener() {
@Override
@ -73,11 +74,13 @@ public class LocationModule extends ReactContextBaseJavaModule {
private final long timeout;
private final double maximumAge;
private final boolean highAccuracy;
private final float distanceFilter;
private LocationOptions(long timeout, double maximumAge, boolean highAccuracy) {
private LocationOptions(long timeout, double maximumAge, boolean highAccuracy, float distanceFilter) {
this.timeout = timeout;
this.maximumAge = maximumAge;
this.highAccuracy = highAccuracy;
this.distanceFilter = distanceFilter;
}
private static LocationOptions fromReactMap(ReadableMap map) {
@ -88,8 +91,10 @@ public class LocationModule extends ReactContextBaseJavaModule {
map.hasKey("maximumAge") ? map.getDouble("maximumAge") : Double.POSITIVE_INFINITY;
boolean highAccuracy =
map.hasKey("enableHighAccuracy") && map.getBoolean("enableHighAccuracy");
float distanceFilter =
map.hasKey("distanceFilter") ? (float) map.getDouble("distanceFilter") : RCT_DEFAULT_LOCATION_ACCURACY;
return new LocationOptions(timeout, maximumAge, highAccuracy);
return new LocationOptions(timeout, maximumAge, highAccuracy, distanceFilter);
}
}
@ -151,7 +156,7 @@ public class LocationModule extends ReactContextBaseJavaModule {
}
if (!provider.equals(mWatchedProvider)) {
locationManager.removeUpdates(mLocationListener);
locationManager.requestLocationUpdates(provider, 1000, 0, mLocationListener);
locationManager.requestLocationUpdates(provider, 1000, locationOptions.distanceFilter, mLocationListener);
}
mWatchedProvider = provider;
} catch (SecurityException e) {