What I did:-
I am using Gimbal beacons and creating a hybrid application using "angular js + ionic + cordova". My application is working good but beacon Entering and Exit takes too long, both in foreground and background. How can I resolve the issue?I am attaching my code snippet below:
Steps:-
First I am calling the delegates from angular using cordova
My iOS delegate methods gets called but after a long delay
didEnterRegion - called after 10 secs
didExitRegion - called after 20-30 secs
I have set Gimbal TRANSMISSION INTERVAL (MS) - 100
My snippet:-
Angular-js snippet:
// Request permission from user to access location info.
cordova.plugins.locationManager.requestAlwaysAuthorization();
// Create delegate object that holds beacon callback functions.
var delegate = new cordova.plugins.locationManager.Delegate();
console.log(delegate)
cordova.plugins.locationManager.setDelegate(delegate);
// Set delegate functions.
delegate.didDetermineStateForRegion = onDidDetermineStateForRegion;
delegate.didRangeBeaconsInRegion = onDidRangeBeaconsInRegion;
delegate.didEnterRegion = onDidRangeBeaconsInRegion
iOS snippet:-
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
[self.queue addOperationWithBlock:^{
[self _handleCallSafely:^CDVPluginResult *(CDVInvokedUrlCommand *command) {
[[self getLogger] debugLog:@"didEnterRegion: %@", region.identifier];
[[self getLogger] debugNotification:@"didEnterRegion: %@", region.identifier];
NSMutableDictionary* dict = [NSMutableDictionary new];
[dict setObject:[self jsCallbackNameForSelector:(_cmd)] forKey:@"eventType"];
[dict setObject:[self mapOfRegion:region] forKey:@"region"];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dict];
[pluginResult setKeepCallbackAsBool:YES];
return pluginResult;
} :nil :NO :self.delegateCallbackId];
}];
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
[self.queue addOperationWithBlock:^{
[self _handleCallSafely:^CDVPluginResult *(CDVInvokedUrlCommand *command) {
[[self getLogger] debugLog:@"didExitRegion: %@", region.identifier];
[[self getLogger] debugNotification:@"didExitRegion: %@", region.identifier];
NSMutableDictionary* dict = [NSMutableDictionary new];
[dict setObject:[self jsCallbackNameForSelector:(_cmd)] forKey:@"eventType"];
[dict setObject:[self mapOfRegion:region] forKey:@"region"];
CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dict];
[pluginResult setKeepCallbackAsBool:YES];
return pluginResult;
} :nil :NO :self.delegateCallbackId];
}];
}
We've noticed similar behavior with native iBeacon region functionality, especially regarding didExitRegion. The behavior seems to vary depending on the iOS version and also application state (foreground/background). I've personally also noticed differences between different devices and generations i.e iPhone 6 vs older iPad mini, which seems to skip some of the broadcasted packets which causes delays.
What iOS version are you using? Are the delays you mentioned consistent or does it get better over time when nearby iBeacons? Especially older iOS versions are prone to this kind of behavior (based on our tests).
Some notes on how we improved the reaction time:
We decided to do our own implementation which uses ranging and our own geofence comparison, which simulates entering and exiting "regions". It's true that this brings some extra work regarding geofence implementation but yields better results.
Obviously this has it's limits when the app is suspended and not running actively at the background. The "location" background mode offers brief windows for the application to do ranging, even when it's at the background. Background modes are heavily regulated by Apple so it requires a proper value added reason.
So all in all, there might be some ways to improve the delay when using the native iBeacon regions but overall if the timing is critical for the app, i'd suggest trying the alternative route explained roughly above.
Disclosure: I work for Proximi.io Proximity Platform