My code is a Native Module called from a react native app, here is the native module code:
code-block
#import "RCTLocationDataManager.h"
#import <CoreLocation/CLLocationManager.h>
#import <React/RCTLog.h>
#import <CoreLocation/CLCircularRegion.h>
@implementation RCTLocationDataManager
{
CLLocationManager * locationManager;
NSDictionary * lastLocationEvent;
}
(dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
RCT_EXPORT_MODULE();
(BOOL)requiresMainQueueSetup
{
return YES; // only do this if your module exports constants or calls UIKit
}
//all methods currently async
RCT_EXPORT_METHOD(initialize:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"Pretending to do something natively: initialize");
resolve(@(true));
}
RCT_EXPORT_METHOD(hasPermissions:(NSString *)permissionType
hasPermissionsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"Pretending to do something natively: hasPermissions %@", permissionType);
BOOL locationAllowed = [CLLocationManager locationServicesEnabled];
resolve(@(locationAllowed));
}
RCT_EXPORT_METHOD(requestPermissions:(NSString *)permissionType
requestPermissionsWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSArray *arbitraryReturnVal = @[@"testing..."];
// location
if (!locationManager) {
RCTLogInfo(@"init locationManager...");
locationManager = [[CLLocationManager alloc] init];
}
locationManager.delegate = self;
locationManager.allowsBackgroundLocationUpdates = true;
locationManager.pausesLocationUpdatesAutomatically = true;
if ([locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
[locationManager requestAlwaysAuthorization];
} else if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[locationManager requestWhenInUseAuthorization];
}
for (CLRegion *region in locationManager.monitoredRegions)
{
[ locationManager stopMonitoringForRegion: region];
}
resolve(arbitraryReturnVal);
}
RCT_EXPORT_METHOD(startMonitoring:(NSArray *)projects)
{
NSLog(@"got projects :%@", projects);
locationManager.distanceFilter = 0;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
for (int i = 0; i < [projects count]; i++) {
NSDictionary* project = [projects objectAtIndex:i];
double longitude = [project[@"attributes"][@"longitude"] doubleValue];
double latitude = [project[@"attributes"][@"latitude"] doubleValue];
NSString *name = project[@"attributes"][@"name"];
CLLocationCoordinate2D centreLoc = {longitude, latitude};
CLLocationDistance regionRadius = [project[@"attributes"][@"geo_radius"] intValue];
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:centreLoc radius:500 identifier:name];
[locationManager startMonitoringForRegion:region];
NSLog(@"setup region:%@", region);
}
// [locationManager startUpdatingLocation];
// [locationManager startMonitoringSignificantLocationChanges];
NSLog(@"monotoring regions:%@", locationManager.monitoredRegions);
// CLCircularRegion *region = CLCircularRegion(CLLocationCoordinate2D(, ), 1000, "location1");
// region.notifyOnEntry = true;
// region.notifyOnExit = false;
// [locationManager startMonitoring:region];
}
(NSArray *)supportedEvents {
return @[@"significantLocationChange", @"didEnterRegion", @"didExitRegion"];
}
(void)locationManager:(CLLocationManager *)manager
didFinishDeferredUpdatesWithError:(NSError *)error{
NSLog(@"Error with Updating");
}
-(void)locationManager:(CLLocationManager *)manager
didFailWithError:(NSError *)error
{
//Failed to recieve user's location
NSLog(@"failed to recived user's locatio");
}
(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion*)region {
RCTLogInfo(@"didEnterRegion : %@", region);
[self sendEventWithName:@"didEnterRegion" body:region.identifier];
}
(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion*)region {
RCTLogInfo(@"didExitRegion : %@", region);
[self sendEventWithName:@"didExitRegion" body:region.identifier];
}
(void)locationManager:(CLLocationManager *)manager
didDetermineState:(CLRegionState)state
forRegion:(CLRegion *)region {
RCTLogInfo(@"didDetermineState region %@", region);
switch (state) {
case CLRegionStateInside:
RCTLogInfo(@"didDetermineState inside region %@", region);
[self sendEventWithName:@"didEnterRegion" body:region.identifier];
break;
case CLRegionStateOutside:
RCTLogInfo(@"didDetermineState OUTSIDE region %@", region);
break;
case CLRegionStateUnknown:
RCTLogInfo(@"didDetermineState UNKNOWN %@", region);
break;
default:
break;
}
}
(void)locationManager:(CLLocationManager *)manager
// didStartMonitoringForRegion:(CLRegionState)state
forRegion:(CLRegion *)region {
RCTLogInfo(@"didStartMonitoringForRegion Already inside region? %@", region);
// if (state == CLRegionStateInside) {
// RCTLogInfo(@"Already inside region %@", region);
// [self locationManager:manager didEnterRegion:region];
// }
}
(void) locationManager:(CLLocationManager *) manager
monitoringDidFailFor:(CLRegion*)region
withError:(NSError *)error {
RCTLogInfo(@"Error monitoring region %@: %@", region, error);
}
@end