Commit 43acaf0f authored by Chris Scott's avatar Chris Scott

Merge branch 'trigger-activities' into edge

parents d6319eb3 72ef5aa7
......@@ -268,6 +268,23 @@ Disable background geolocation tracking.
bgGeo.stop();
```
####`getCurrentPosition(successFn, failureFn)`
Retrieves the current position. This method instructs the native code to fetch exactly one location using maximum power & accuracy. The native code will persist the fetched location to SQLite just as any other location in addition to POSTing to your configured `#url` (if you've enabled the HTTP features). In addition to your supplied `callbackFn`, the plugin will also execute the `callback` provided to `#configure`. Your provided `successFn` will be executed with the same signature as that provided to `#configure`:
######@param {Object} location The Location data
######@param {Integer} taskId The taskId used to send to bgGeo.finish(taskId) in order to signal completion of your callbackFn
```
bgGeo.getCurrentPosition(function(location, taskId) {
// This location is already persisted to plugin’s SQLite db.
// If you’ve configured #autoSync: true, the HTTP POST has already started.
console.log(“- Current position received: “, location);
bgGeo.finish(taskId);
});
```
####`changePace(enabled, successFn, failureFn)`
Initiate or cancel immediate background tracking. When set to ```true```, the plugin will begin aggressively tracking the devices Geolocation, bypassing stationary monitoring. If you were making a "Jogging" application, this would be your [Start Workout] button to immediately begin GPS tracking. Send ```false``` to disable aggressive GPS monitoring and return to stationary-monitoring mode.
......
This diff is collapsed.
......@@ -12,17 +12,20 @@
@property (nonatomic, strong) NSString* syncCallbackId;
@property (nonatomic) UIBackgroundTaskIdentifier syncTaskId;
@property (nonatomic, strong) NSString* locationCallbackId;
@property (nonatomic, strong) NSMutableArray* currentPositionListeners;
@property (nonatomic, strong) NSMutableArray* geofenceListeners;
@property (nonatomic, strong) NSMutableArray* stationaryRegionListeners;
@property (nonatomic, strong) NSMutableArray* motionChangeListeners;
- (void) configure:(CDVInvokedUrlCommand*)command;
- (void) start:(CDVInvokedUrlCommand*)command;
- (void) stop:(CDVInvokedUrlCommand*)command;
- (void) finish:(CDVInvokedUrlCommand*)command;
- (void) error:(CDVInvokedUrlCommand*)command;
- (void) onPaceChange:(CDVInvokedUrlCommand*)command;
- (void) changePace:(CDVInvokedUrlCommand*)command;
- (void) setConfig:(CDVInvokedUrlCommand*)command;
- (void) addStationaryRegionListener:(CDVInvokedUrlCommand*)command;
- (void) addMotionChangeListener:(CDVInvokedUrlCommand*)command;
- (void) getStationaryLocation:(CDVInvokedUrlCommand *)command;
- (void) getLocations:(CDVInvokedUrlCommand *)command;
- (void) sync:(CDVInvokedUrlCommand *)command;
......@@ -32,6 +35,7 @@
- (void) removeGeofence:(CDVInvokedUrlCommand *)command;
- (void) getGeofences:(CDVInvokedUrlCommand *)command;
- (void) onGeofence:(CDVInvokedUrlCommand *)command;
- (void) getCurrentPosition:(CDVInvokedUrlCommand *)command;
- (void) playSound:(CDVInvokedUrlCommand *)command;
@end
......@@ -10,16 +10,17 @@
NSDictionary *config;
}
@synthesize syncCallbackId, syncTaskId, locationCallbackId, geofenceListeners, stationaryRegionListeners;
@synthesize syncCallbackId, syncTaskId, locationCallbackId, geofenceListeners, stationaryRegionListeners, motionChangeListeners, currentPositionListeners;
- (void)pluginInitialize
{
bgGeo = [[TSLocationManager alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onLocationChanged:) name:@"TSLocationManager.location" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onStationaryLocation:) name:@"TSLocationManager.stationary" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMotionChange:) name:@"TSLocationManager.motionchange" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onEnterGeofence:) name:@"TSLocationManager.geofence" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onSyncComplete:) name:@"TSLocationManager.sync" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onLocationManagerError:) name:@"TSLocationManager.error" object:nil];
}
/**
......@@ -54,6 +55,9 @@
- (void) start:(CDVInvokedUrlCommand*)command
{
[bgGeo start];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool: true];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
/**
* Turn it off
......@@ -61,6 +65,8 @@
- (void) stop:(CDVInvokedUrlCommand*)command
{
[bgGeo stop];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool: false];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
- (void) getOdometer:(CDVInvokedUrlCommand*)command
{
......@@ -78,10 +84,12 @@
* Change pace to moving/stopped
* @param {Boolean} isMoving
*/
- (void) onPaceChange:(CDVInvokedUrlCommand *)command
- (void) changePace:(CDVInvokedUrlCommand *)command
{
BOOL moving = [[command.arguments objectAtIndex: 0] boolValue];
[bgGeo onPaceChange:moving];
[bgGeo changePace:moving];
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsBool: moving];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
/**
......@@ -90,8 +98,9 @@
- (void)onLocationChanged:(NSNotification*)notification {
CLLocation *location = [notification.userInfo objectForKey:@"location"];
NSDictionary *locationData = [bgGeo locationToDictionary:location];
NSDictionary *params = @{
@"location": [bgGeo locationToDictionary:location],
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult* result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
......@@ -100,18 +109,52 @@
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:self.locationCallbackId];
}];
if ([self.currentPositionListeners count]) {
for (NSString *callbackId in self.currentPositionListeners) {
NSDictionary *params = @{
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
[result setKeepCallbackAsBool:NO];
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
[self.currentPositionListeners removeAllObjects];
}
}
- (void) onStationaryLocation:(NSNotification*)notification
- (void) onMotionChange:(NSNotification*)notification
{
if (![self.stationaryRegionListeners count]) {
if (![self.stationaryRegionListeners count] && ![self.motionChangeListeners count]) {
return;
}
BOOL isMoving = [[notification.userInfo objectForKey:@"isMoving"] boolValue];
CLLocation *location = [notification.userInfo objectForKey:@"location"];
NSDictionary *locationData = [bgGeo locationToDictionary:location];
// @deprecated stationaryRegionListeners in favour of dual-function motionChangeListeners
if (!isMoving) {
for (NSString *callbackId in self.stationaryRegionListeners) {
NSLog(@"- CALLBACK: %@", callbackId);
NSDictionary *params = @{
@"isMoving": @(isMoving),
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:params];
[result setKeepCallbackAsBool:YES];
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
}
for (NSString *callbackId in self.motionChangeListeners) {
NSDictionary *params = @{
@"isMoving": @(isMoving),
@"location": locationData,
@"taskId": @([bgGeo createBackgroundTask])
};
......@@ -120,7 +163,6 @@
[self.commandDelegate runInBackground:^{
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}];
}
}
......@@ -149,6 +191,9 @@
- (void) onSyncComplete:(NSNotification*)notification
{
if (syncCallbackId == nil) {
return;
}
NSDictionary *params = @{
@"locations": [notification.userInfo objectForKey:@"locations"],
@"taskId": @(syncTaskId)
......@@ -217,6 +262,14 @@
[self.stationaryRegionListeners addObject:command.callbackId];
}
- (void) addMotionChangeListener:(CDVInvokedUrlCommand*)command
{
if (self.motionChangeListeners == nil) {
self.motionChangeListeners = [[NSMutableArray alloc] init];
}
[self.motionChangeListeners addObject:command.callbackId];
}
- (void) addGeofence:(CDVInvokedUrlCommand*)command
{
NSDictionary *cfg = [command.arguments objectAtIndex:0];
......@@ -261,7 +314,6 @@
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}
- (void) onGeofence:(CDVInvokedUrlCommand*)command
{
if (self.geofenceListeners == nil) {
......@@ -270,6 +322,22 @@
[self.geofenceListeners addObject:command.callbackId];
}
- (void) getCurrentPosition:(CDVInvokedUrlCommand*)command
{
if (![bgGeo isEnabled]) {
NSLog(@"- CDVBackgroundGeolocation#getCurrentPosition cannot be used when plugin is disabled");
// If plugin isn't enabled, return 401 Unauthorized
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:401];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
return;
}
if (self.currentPositionListeners == nil) {
self.currentPositionListeners = [[NSMutableArray alloc] init];
}
[self.currentPositionListeners addObject:command.callbackId];
[bgGeo updateCurrentPosition];
}
- (void) playSound:(CDVInvokedUrlCommand*)command
{
int soundId = [[command.arguments objectAtIndex:0] integerValue];
......@@ -295,8 +363,26 @@
UIBackgroundTaskIdentifier taskId = [[command.arguments objectAtIndex: 0] integerValue];
NSString *error = [command.arguments objectAtIndex:1];
[bgGeo error:taskId message:error];
}
- (void) onLocationManagerError:(NSNotification*)notification
{
NSLog(@" - onLocationManagerError: %@", notification.userInfo);
NSString *errorType = [notification.userInfo objectForKey:@"type"];
if ([errorType isEqualToString:@"location"]) {
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsInt:[[notification.userInfo objectForKey:@"code"] intValue]];
if ([self.currentPositionListeners count]) {
[result setKeepCallbackAsBool:NO];
for (NSString *callbackId in self.currentPositionListeners) {
[self.commandDelegate sendPluginResult:result callbackId:callbackId];
}
[self.currentPositionListeners removeAllObjects];
}
[self.commandDelegate sendPluginResult:result callbackId:locationCallbackId];
}
}
/**
* If you don't stopMonitoring when application terminates, the app will be awoken still when a
* new location arrives, essentially monitoring the user's location even when they've killed the app.
......
......@@ -6,6 +6,7 @@
@property (nonatomic) CLLocationDistance odometer;
@property (nonatomic, strong) CLLocationManager* locationManager;
- (void) configure:(NSDictionary*)config;
- (void) start;
- (void) stop;
......@@ -14,7 +15,7 @@
- (UIBackgroundTaskIdentifier) createBackgroundTask;
- (void) stopBackgroundTask:(UIBackgroundTaskIdentifier)taskId;
- (void) error:(UIBackgroundTaskIdentifier)taskId message:(NSString*)message;
- (void) onPaceChange:(BOOL)value;
- (void) changePace:(BOOL)value;
- (void) setConfig:(NSDictionary*)command;
- (NSDictionary*) getStationaryLocation;
- (void) onSuspend:(NSNotification *)notification;
......@@ -25,6 +26,7 @@
- (void) addGeofence:(NSString*)identifier radius:(CLLocationDistance)radius latitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude notifyOnEntry:(BOOL)notifyOnEntry notifyOnExit:(BOOL)notifyOnExit;
- (BOOL) removeGeofence:(NSString*)identifier;
- (NSArray*) getGeofences;
- (void) updateCurrentPosition;
- (void) playSound:(SystemSoundID)soundId;
@end
......@@ -6,7 +6,7 @@
<dict>
<key>Headers/TSLocationManager.h</key>
<data>
++tA66F/FJQ/qMup0fGBER20r9U=
dTpEJTYyFANcuJNr9upQ8PrgD3Q=
</data>
<key>Info.plist</key>
<data>
......@@ -21,7 +21,7 @@
<dict>
<key>Headers/TSLocationManager.h</key>
<data>
++tA66F/FJQ/qMup0fGBER20r9U=
dTpEJTYyFANcuJNr9upQ8PrgD3Q=
</data>
<key>Modules/module.modulemap</key>
<data>
......
......@@ -83,7 +83,7 @@ module.exports = {
exec(success || function() {},
failure || function() {},
'BackgroundGeoLocation',
'onPaceChange',
'changePace',
[isMoving]);
},
/**
......@@ -112,6 +112,7 @@ module.exports = {
},
/**
* Add a stationary-region listener. Whenever the devices enters "stationary-mode", your #success callback will be executed with #location param containing #radius of region
* @deprecated in favour of dual-function #onMotionChange
* @param {Function} success
* @param {Function} failure [optional] NOT IMPLEMENTED
*/
......@@ -136,6 +137,35 @@ module.exports = {
'addStationaryRegionListener',
[]);
},
/**
* Add a movement-state-change listener. Whenever the devices enters "stationary" or "moving" mode, your #success callback will be executed with #location param containing #radius of region
* @param {Function} success
* @param {Function} failure [optional] NOT IMPLEMENTED
*/
onMotionChange: function(success, failure) {
var me = this;
success = success || function(isMoving, location, taskId) {
me.finish(taskId);
};
var callback = function(params) {
var isMoving = params.isMoving;
var location = params.location;
var taskId = params.taskId || 'task-id-undefined';
if (!isMoving) {
me.stationaryLocation = location;
}
me._runBackgroundTask(taskId, function() {
success.call(me, isMoving, location, taskId);
}, failure);
};
exec(callback,
failure || function() {},
'BackgroundGeoLocation',
'addMotionChangeListener',
[]);
},
getLocations: function(success, failure) {
if (typeof(success) !== 'function') {
throw "BackgroundGeolocation#getLocations requires a success callback";
......@@ -263,6 +293,31 @@ module.exports = {
[]);
},
/**
* Fetch the current position
*/
getCurrentPosition: function(success, failure) {
var me = this;
success = success || function(location, taskId) {
me.finish(taskId);
};
var mySuccess = function(params) {
var location = params.location || params;
var taskId = params.taskId || 'task-id-undefined';
// Transform timestamp to Date instance.
if (location.timestamp) {
location.timestamp = new Date(location.timestamp);
}
me._runBackgroundTask(taskId, function() {
success.call(this, location, taskId);
});
}
exec(mySuccess || function() {},
failure || function() {},
'BackgroundGeoLocation',
'getCurrentPosition',
[]);
},
/**
* Play a system sound. This is totally experimental.
* iOS http://iphonedevwiki.net/index.php/AudioServices
* Android:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment