iOS: didStartMonitoringForRegion not called - ios

I am running this off my iPhone 4 device.
First, here is the relevant code:
-(void)applicationDidBecomeActive:(UIApplication *)application
{
CLLocationDegrees latitude = 45.50568;
CLLocationDegrees longitude = -73.21352;
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(latitude, longitude);
CLLocationDistance radius = 200.0;
CLRegion *myRegion = [[CLRegion alloc] initCircularRegionWithCenter:center radius:radius identifier:#"region1"];
[locationManager startMonitoringForRegion:myRegion];
}
But at no point whatsoever does didStartMonitoringForRegion get called, not even monitoringDidFailForRegion gets called.
What am I doing wrong? My device supports regional monitoring, I can't see what the problem is.

Related

Current user location is not shown (Blue Dot)

I am trying to do very basic thing in an existing project to show user location (Blue Dot) and do location update. I have all delegate methods, settings are on for show user location and I can make it work in new project.
Although I am using real device it is not asking me that "do you want to use location services in this app?" or under security->location services I can't see my application next to others. Howvever when I checked [CLLocationManager locationServicesEnabled]; it returns YES.
I have also tried it with simulator and virtual location San Francisco. Same result, no even blue dot.
One tip. This project was started to build about 2 years ago and now I am setting deployment target to 7.1.
Any help will be appreciated.
Some code I ve used may help:
in viewDidLoad
mapCheckinAcity.delegate = self;
[mapCheckinAcity setMapType:MKMapTypeStandard];
[mapCheckinAcity setZoomEnabled:YES];
[mapCheckinAcity setScrollEnabled:YES];
mapCheckinAcity.showsUserLocation = YES;
self.locationManager = [[CLLocationManager alloc]init];
BOOL bl = [CLLocationManager locationServicesEnabled];
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
self.locationManager.delegate = self;
[self.locationManager startUpdatingLocation];
Try this:
CLLocationCoordinate2D location = [self geoCodeUsingAddress:str];
location.latitude = (double) location.latitude;
location.longitude = (double) location.longitude;
MKCoordinateSpan span;
span.latitudeDelta=40.01;
span.longitudeDelta=40.01;
MKCoordinateRegion region = {location,span};
MapAnnotation *newAnnotation = [[MapAnnotation alloc] initWithCoordinate:location];
[self.mapview addAnnotation:newAnnotation];
[mapview setRegion:region];
[self.view addSubview:mapview];
Try enabling Location Services in iOS settings
Settings > Privacy > Location Services > and enable access for your application

Geofencing is not working properly

In my application I want do geofencing. I have list of locations, for which I am setting geofencing regions. All location have radius 100m. Following is the code to set Region:
CLLocationCoordinate2D cord;
cord.latitude = [location.latitude doubleValue];
cord.longitude = [location.longtitude doubleValue];
CLLocationDistance regionRadius = location.radius;
CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:cord radius:regionRadius identifier:[NSString stringWithFormat:#"%d",location.locId]];
[appDelegate.locationManager startMonitoringForRegion:region];
My problem is that, its not working properly. For debugging, in didEnterRegion delegate added distance calculation in between current location and region location some times this distance is more then 1500m.
Following is the code to calculate distance between current location and region location:
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
CLLocation *loc1 = locationManager.location;
CLLocation *loc2 = [[CLLocation alloc] initWithLatitude:region.center.latitude longitude:region.center.longitude];
double dist = [loc1 distanceFromLocation:loc2];
}
Any idea, why -locationManager:didEnterRegion: get triggered such a wrong way?
This is a glitch in iOS Region Monitoring and I have faced the similar issue with Geofencing and I have found a way to solve that problem.
I have posted the question here and I have answered myself, I have a blog post on that as well:-
Region Monitoring Glitch on iOS 7 - Multiple Notifications at the same time
iOS Region Monitoring and Location Manager

Problems with MKMapView on first use

I have an MKMapView but when the user logs on the first time and allows location services, it doesn't show there location. If they leave the view and come back, it works. I am using what is listed bellow to solve the problem. It solves the problem but then the user can no longer zoom because when there location is updated, it takes them back to the specified location. How would I fix the first problem while making scrolling work.
Here is what I am using:
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
MKUserLocation *myLocation = [self.schoolMap userLocation];
CLLocationCoordinate2D coord = [[myLocation location] coordinate];
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(coord, 9000, 9000);
[self.schoolMap setRegion:region animated:NO];
}
Do not use location manager at all. Just tell the map view to track the user's location. Then implement this delegate method:
- (void)mapView:(MKMapView *)mapView
didUpdateUserLocation:(MKUserLocation *)userLocation {
CLLocationCoordinate2D coordinate = userLocation.location.coordinate;
MKCoordinateRegion reg =
MKCoordinateRegionMakeWithDistance(coordinate, 600, 600);
mapView.region = reg;
}
Now, that will keep trying to set the map every time the user moves, so if you don't want that, add a BOOL switch so that you only do this the first time (when the map first gets the user location).
It is possible that you did not received user's location by the time you set the region. There's a way to handle this situation by letting the mapView shows the user's location whenever it got to as follows:
CLLocation *location = [[self.schoolMap userLocation] location];
bool hasLocation = location!=nil;
if (!hasLocation) {
[self.mapView showsUserLocation];
} else {
CLLocationCoordinate2D zoomLocation = location.coordinate;
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 2000, 2000);
[self.mapView setRegion:viewRegion animated:NO];
Note that this does not demand you update the location on a regular basis.

MKMapview ios not showing current location when app is loaded first time

I have a MKMapView on my app. This is iOS6.
-(void)viewDidLoad
{
.....
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(#"Update locations is hit");
NSLog(#"379 the locations count is %d",locations.count);
CLLocation *obj = [locations lastObject];
NSLog(#"the lat is %f", obj.coordinate.latitude);
NSLog(#"the long is %f", obj.coordinate.longitude);
NSLog(#"the horizontal accuracy is %f",obj.horizontalAccuracy);
NSLog(#"the vertical accuracty is %f",obj.verticalAccuracy);
if (obj.coordinate.latitude != 0 && obj.coordinate.longitude != 0)
{
CLLocationCoordinate2D currrentCoordinates ;
currrentCoordinates.latitude = obj.coordinate.latitude;
currrentCoordinates.longitude = obj.coordinate.longitude;
}
....more computation
[locationManager stopUpdatingLocation];
}
When I first load the app, my location is showing little far away. Some times miles away. I also have a reset location button and if I click that map shows correct location. This is what I have in reset location button click:
- (IBAction)btnResetLocationClick:(UIButton *)sender
{
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
[locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager startUpdatingLocation];
}
So how do I make the app get the correct current location on load up itself. Is there a way for the app to tell the map to wait for few milliseconds and then update. Or any other idea? Please let me know. If you need more information, please ask. Thanks.
What you could do is to:
do not turn off location services in didUpdateLocations automatically, but rather;
turn off location services in didUpdateLocations only if you're sufficiently happy with the horizontalAccuracy; and
even if you don't get the desired accuracy, turn off location services after a certain amount of time has passed.
Thus, didUpdateLocations might look like:
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocation *location = [locations lastObject];
// do whatever you want with the location
// finally turn off location services if we're close enough
//
// I'm using 100m; maybe that's too far for you, but 5m is probably too small
// as you frequently never get that accurate of a location
if (location.horizontalAccuracy > 0 && location.horizontalAccuracy < 100)
[locationManager stopUpdatingLocation];
}
And then in viewDidLoad, turn if off after a certain period of time has passed (you might want to check some status variable that you set if you've already turned off location services):
-(void)viewDidLoad
{
.....
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager setDesiredAccuracy:kCLLocationAccuracyBestForNavigation];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager startUpdatingLocation];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 60.0 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[locationManager stopUpdatingLocation];
});
}
Original answer:
I don't see where you're updating your map to be around your location. I'd expect to see something like:
self.mapView.centerCoordinate = location.coordinate;
or like:
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(location.coordinate, 300, 300);
[self.mapView setRegion:region];
I'd also suggest, rather than turning off location services immediately (since frequently the first few locations are not that accurate), leave it on for a bit and let it hone in on your location until the horizontalAccuracy and verticalAccuracy fall within a certain predetermined limit. Look at those accuracy figures for a few calls to didUpdateLocations and you'll see what I mean.
I originally thought you were getting a negative horizontalAccuracy at which point I suggested implementing didFailToLocateUserWithError because according to horizontalAccuracy, "A negative value indicates that the location’s latitude and longitude are invalid." Hopefully you get an error that describes what the issue is. Even if you're not currently getting a negative horizontalAccuracy, you might want to implement this method, just to make sure you're handling any errors correctly.
You can't make the GPS in the iPhone more accurate in your app, but you can check that the result is accurate before carrying on. Right now you're only checking the lat and long aren't 0, but if you check obj's horizontalAccuracy then you'll know when the location information is good enough. Don't stopUpdatingLoation until that happens.

MKMapView doesn't scroll and doesn't not zoom

I have a MapView and marked where the user's location and nearby there are other annotationView of various types regarding tourist attractions. I want the MapView is scrollable and zoomable to see all annotationView of the city, but when I move the MapView returns immediately centered shooting, ugly looking.
this is the code in MapViewController.m
- (void)viewDidLoad{
//.....
self.mapView.zoomEnabled=YES;
self.mapView.scrollEnabled = YES;
//......
}
- (void) locationManager:(CLLocationManager *) manager
didUpdateToLocation:(CLLocation *) newLocation
fromLocation:(CLLocation *) oldLocation {
//......
self.coordinate = CLLocationCoordinate2DMake(self.latitudine, self.longitudine);
CLLocationCoordinate2D min = CLLocationCoordinate2DMake(self.coordinate.latitude -0.005,
self.coordinate.longitude-0.005);
CLLocationCoordinate2D max = CLLocationCoordinate2DMake(self.coordinate.latitude+0.005,
self.coordinate.longitude+0.005);
CLLocationCoordinate2D center = CLLocationCoordinate2DMake((max.latitude + min.latitude)
/ 2.0, (max.longitude + min.longitude) / 2.0);
MKCoordinateSpan span = MKCoordinateSpanMake(max.latitude - min.latitude, max.longitude -
min.longitude);
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
self.mapView.region= region;
[mapView setRegion:region animated:TRUE];
//......
}
I think it is because the update is getting called constantly, so it will center the screen all the time with your mapview setregion bit.
When you declared your locationManager bet sure to set the sensitivity.
self.locationManager.distanceFilter = 10.0f;
This will only call the update if it changes more than 10 meters.
Everytime the device notices it has changed location, you are zooming the map to self.latitudine and self.longitudine. In the code you have shown you are not setting those values to anything new. Do you mean to be zooming in on the newLocation coordinates?

Resources