126 lines
3.4 KiB
JavaScript
126 lines
3.4 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
* @providesModule Geolocation
|
|
* @flow
|
|
*/
|
|
'use strict';
|
|
|
|
var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
|
var RCTLocationObserver = require('NativeModules').LocationObserver;
|
|
|
|
var invariant = require('invariant');
|
|
var logError = require('logError');
|
|
var warning = require('warning');
|
|
|
|
var subscriptions = [];
|
|
|
|
var updatesEnabled = false;
|
|
|
|
type GeoOptions = {
|
|
timeout: number;
|
|
maximumAge: number;
|
|
enableHighAccuracy: bool;
|
|
}
|
|
|
|
/**
|
|
* You need to include the `NSLocationWhenInUseUsageDescription` key
|
|
* in Info.plist to enable geolocation. Geolocation is enabled by default
|
|
* when you create a project with `react-native init`.
|
|
*
|
|
* Geolocation follows the MDN specification:
|
|
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
|
|
*/
|
|
var Geolocation = {
|
|
|
|
/*
|
|
* Invokes the success callback once with the latest location info. Supported
|
|
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
|
|
*/
|
|
getCurrentPosition: function(
|
|
geo_success: Function,
|
|
geo_error?: Function,
|
|
geo_options?: GeoOptions
|
|
) {
|
|
invariant(
|
|
typeof geo_success === 'function',
|
|
'Must provide a valid geo_success callback.'
|
|
);
|
|
RCTLocationObserver.getCurrentPosition(
|
|
geo_options || {},
|
|
geo_success,
|
|
geo_error || logError
|
|
);
|
|
},
|
|
|
|
/*
|
|
* Invokes the success callback whenever the location changes. Supported
|
|
* options: timeout (ms), maximumAge (ms), enableHighAccuracy (bool)
|
|
*/
|
|
watchPosition: function(success: Function, error?: Function, options?: GeoOptions): number {
|
|
if (!updatesEnabled) {
|
|
RCTLocationObserver.startObserving(options || {});
|
|
updatesEnabled = true;
|
|
}
|
|
var watchID = subscriptions.length;
|
|
subscriptions.push([
|
|
RCTDeviceEventEmitter.addListener(
|
|
'geolocationDidChange',
|
|
success
|
|
),
|
|
error ? RCTDeviceEventEmitter.addListener(
|
|
'geolocationError',
|
|
error
|
|
) : null,
|
|
]);
|
|
return watchID;
|
|
},
|
|
|
|
clearWatch: function(watchID: number) {
|
|
var sub = subscriptions[watchID];
|
|
if (!sub) {
|
|
// Silently exit when the watchID is invalid or already cleared
|
|
// This is consistent with timers
|
|
return;
|
|
}
|
|
|
|
sub[0].remove();
|
|
// array element refinements not yet enabled in Flow
|
|
var sub1 = sub[1]; sub1 && sub1.remove();
|
|
subscriptions[watchID] = undefined;
|
|
var noWatchers = true;
|
|
for (var ii = 0; ii < subscriptions.length; ii++) {
|
|
if (subscriptions[ii]) {
|
|
noWatchers = false; // still valid subscriptions
|
|
}
|
|
}
|
|
if (noWatchers) {
|
|
Geolocation.stopObserving();
|
|
}
|
|
},
|
|
|
|
stopObserving: function() {
|
|
if (updatesEnabled) {
|
|
RCTLocationObserver.stopObserving();
|
|
updatesEnabled = false;
|
|
for (var ii = 0; ii < subscriptions.length; ii++) {
|
|
var sub = subscriptions[ii];
|
|
if (sub) {
|
|
warning('Called stopObserving with existing subscriptions.');
|
|
sub[0].remove();
|
|
// array element refinements not yet enabled in Flow
|
|
var sub1 = sub[1]; sub1 && sub1.remove();
|
|
}
|
|
}
|
|
subscriptions = [];
|
|
}
|
|
}
|
|
};
|
|
|
|
module.exports = Geolocation;
|