Location manager region monitoring - ios

I am using following apple cllocation manager region monitoring methods:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLCircularRegion *)region
{
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLCircularRegion *)region
{
}
the problem is that these method does not get called when application is in suspended state and not running.Any help would be appreciated. thanks

Try to use significant location change instead of start updating location.Also there is a limit of radius to monitor ,minimum radius should be 100 m

Related

Keep monitoring user's location whenever it changes its position

I am new in location services. I have used startMonitoringSignificantLocationChanges and (void)locationManager:(CLLocationManager *)manager didUpdateToLocation: (CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation method but it is not getting called as I change location value. I want to fetch location value whenever user change its location.How should i achieve this? Please help me to resolve. Thanks in advance.
You need to implement "didUpdateLocations" delegate method . Here is sample
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"locations : %#",locations.description);
CLLocation *currentLocation = [locations lastObject];
NSLog(#"current location : %f %f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
}
In iOS 8 you need to do two extra things to get location working:
1. add one or both of the following keys to your Info.plist file:
NSLocationWhenInUseUsageDescription
NSLocationAlwaysUsageDescription
Next you need to request authorization for the corresponding location method, WhenInUse or Background. Use one of these calls:
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager requestAlwaysAuthorization];
For details refer following link. http://nevan.net/2014/09/core-location-manager-changes-in-ios-8/

Region Monitoring only active on boundary cross?

I'm investigating the use of region monitoring for my app. Basically, I want to define a circle area and if the user is outside this circle, then the app won't work.
As I understand it, region monitoring only checks to see if the user crosses the boundary.
If this is the case, can somebody point me in the direction of a tutorial/blogpost which can help me achieve my goal?
Region Monitoring active on both if user comes in the boundary and goes out from boundary
Following methods are useful to check user comes in or goes out from particular defined boundary area :
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
NSLog(#"User Enters in Region");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
NSLog(#"User Goes out from Region");
}
calculate the distance from current location to center of circle.
If distance > radius then outside.
You can use regions for monitoring user's in/out activity but normally you could register for Significant Location Change and then check whether user's location is in some limited distance from the point. You can easily calculate distance between two CLLocation points by calling on one sth like this:
[myLoc distanceFromLocation:locationOfCenterOfCircle]
and compare it with radius. Method above returns result in meters. In this case worth reading will be this especially about Significant Location Change.
You can perform a requestStateForRegion:(CLRegion *) on the CLLocationManager.
This way the delegate class' delegate method :
-(void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region will be fired.
In there you can check if you're inside the region or outside.
So basically if you request the state somewhere near the beginning of your app, you can determine whether the user is in or outside your fence.
That'd make something like :
-(void) locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
if (state == CLRegionStateInside){
// Inside geofence
} else {
// Keep state disabled
}

didUpdateLocations and didUpdateToLocation

Supporting both iOS 5 and 6, one should call didUpdateLocations from didUpdateToLocation.
How do you make the call and build the Locations array? Any code sample, please?
Thank you.
You don't call those routines. The system, CoreLocation specifically, calls them.
I think this exact code is displayed in the WWDC 2012 session, Staying on Track with Location Services:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
[self locationManager:manager didUpdateLocations:#[newLocation]];
}
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
// your location handling code
}

iOS remove overlay only when I through the region

I created many overlays in mapView with this code:
MKCircle *circle = [MKCircle circleWithCenterCoordinate:userLocation.coordinate radius:1000];
[mapView addOverlay:circle];
I would like to remove one by one only when I execute methode:
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
My problem is: when I'm coming out of a region, do not know what I went through overlay.
Any idea how I can remove those?
Thank you.
You are going to want to monitor the regions corresponding to your circles.
Create your CLRegion:
- (id)initCircularRegionWithCenter:(CLLocationCoordinate2D)center radius:(CLLocationDistance)radius identifier:(NSString *)identifier
Monitor with CLLocationManager:
- (void)startMonitoringForRegion:(CLRegion *)region
Which will send events to your listener, so you can add/remove the overlays when you receive the events:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
Probably the easiest way for you will be to store the relationship between MKCircle objects and the corresponding CLRegion objects, so you can update your map appropriately.

Does startMonitoringForRegion actually work?

I've been trying to use startMonitoringForRegion for while, but experiencing problems to capture enter/exit events. When I launch the app on simulator and moved to the location I specified, I get 1 enter event, but enter events never triggered again. Can somebody let me know if I'm doing correctly?
test.h
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface EWViewController : UIViewController<CLLocationManagerDelegate>
{
CLLocationManager *locman;
}
#end
test.m
- (void)viewDidLoad
{
if(locman == nil)
locman = [[CLLocationManager alloc]init];
locman.delegate = self;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(37.787359, -122.408227);
CLRegion *region = [[CLRegion alloc]initCircularRegionWithCenter:coord radius:1000.0 identifier:#"SF"];
[locman startMonitoringForRegion:region desiredAccuracy:kCLLocationAccuracyKilometer];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void) locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(#"ENTER");
}
- (void) locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(#"EXIT");
}
I have been using region monitoring for a geofence feature in my app for about 6 months and I have found it to be very precise. Once you have everything wired up correctly, it can be used to track enter and exit events quite well.
While you can get even better and more precise readings from -didUpdateToLocation, you will have to trade off battery life to get it. If you only need occasional location updates, it should be fine. If you need constant monitoring for specific locations, region monitoring is the way to go.
I have found that -startMonitoringForSignificantLocation is not accurate at all and not very practical. It relies solely on cell tower transitions and triangulation. It also can't be used to test in the simulator for this very reason. Hope some of this information helps you out.
Yes it works, but it is very very unprecised for the current moment. (I tested it in Russia)
I recommend you using this instead:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation;

Resources