I'm not using this for driving directions or similar. I have a few annotations and want a trigger when user is in the vicinity of one of those, so I can alert the user.
It seems didUpdateToLocation is called only once per startUpdatingLocation call? At least when I NSLog within that method, I only get one line in console. No, I'm not walking around with the iphone.
So: What is the correct way to set up a continuous monitoring of userLocation and get a "callback" (either when 3-4 seconds have passed or when user has moved say, 10 meters)?
As you probably know, this is the code to initialize and start the location manager:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
[locationManager startUpdatingLocation];
And implement didUpdateToLocation like this:
- (void) locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation*) oldLocation
{
// This will be called every time the device has any new location information.
}
The system will call didUpdateToLocation every time there is an update to the location. If the system does not detect a change in location didUpdateToLocation will not be called. The only thing you can do is to set the distanceFilter and desiredAccuracy like i did in the example to give you the highest accuracy.
Update
Use kCLLocationAccuracyBest instead of kCLLocationAccuracyNearestTenMeters for more accuracy.
Related
My app needs to record (as precisely as possible) the user's location and movement over time. If I let the device sleep, the GPS accuracy seems to be automatically reduced. I can stop it from sleeping but obviously that is a further drain on the battery. I would like to allow the display to sleep, but maintain the max accuracy for the locationmanager. I have Location updates ticked in the Background Modes section. My code looks like this ...
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
locationManager.distanceFilter = 1
locationManager.activityType = .Fitness
locationManager.requestAlwaysAuthorization()
locationManager.pausesLocationUpdatesAutomatically = false
locationManager.startUpdatingLocation()
UIApplication.sharedApplication().idleTimerDisabled = true
I would really like to remove that last line, but all the testing I have done on a 4s suggests that as soon as the device sleeps it loses accuracy.
Assuming it is iOS 9 you also need this line:
locationManager.allowsBackgroundLocationUpdates = true;
By default this var is set to false, and that means iOS will not deliver location updates to a suspended app.
I just want to say that I have read everything about filtering old locations etc, but this is not the issue. What I just noticed when testing my app on a real iPhone device, was that when I change the "date & time" in "Settings" in the device, the newLocation I get from locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation gives me the same "date & time" as I have in my iPhone device.
I need to get the real timestamp according to network time, and not the phone's, because then I can manipulate the data. How on earth am I supposed to achieve this, did I miss something?
Btw, my locationmanager look like this:
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
You won't get access to the raw GPS data (with a real timestamp). Why not use an actual ntp server instead?
Hello Friend i have seen many post regarding accuracy problem with gps but its not working all the time
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSString *latstr = [NSString stringWithFormat:#"%f", newLocation.coordinate.latitude];
NSString *longstring=[NSStringstringWithFormat:#"%f",newLocation.coordinate.longitude];
if (abs(howRecent)>5.0)
{
[self.locationManager startUpdatingLocation];
return;
}
if(abs(newLocation.horizontalAccuracy)<0.0f)
{
[self.locationManager startUpdatingLocation];
return;
}
if(newLocation.horizontalAccuracy>65.0f)
{
[self.locationManager startUpdatingLocation];
return;
}
self.latstring = [latstr copy];
self.longstr = [longstring copy];
if((updateLocationFirst||loadFirstView))
{
[[NSUserDefaults standardUserDefaults]setObject:latstring forKey:#"Latitude"];
[[NSUserDefaults standardUserDefaults]setObject:longstr forKey:#"Longitude"];
[self displayParticularDaySpecial];
loadFirstView=FALSE;
updateLocationFirst=FALSE;
[self.locationManager stopUpdatingLocation];
}
}
Here the problem is I am sending the latitude and longitude to the google api with respect to some addresses if i am decreasing the accuracy value its taking lot of time to load and this value is having problem when you reach at destination with respect to destination with 0.6 miles difference.
You should refer to the Location Awareness Programming Guide which provides excellent programming examples for determining your location.
As you'll see in the demo in that document, when you start the standard location manager, you generally tell it what accuracy you require. And once you start the location manager, you don't have to start it again (like you appear to be doing in your code sample). The didUpdateLocations method will be called again and again, with increasing accuracy, all on its own. You don't need to start the location manager again ... it keeps going until you turn it off. By definition, if you're in didUpdateLocations, it means it's already on.
I also notice that you're using the old didUpdateToLocation. If you're programming for iOS 6, you really want to use didUpdateLocations, which is the current version of that CLLocationManagerDelegate method.
Finally, you mention it takes a long time to get your location. That's very possible. In fact, in certain areas, you will never get very close (or any location at all). Your app should assume that accurate locations will take a while, and you should gracefully handle if you never get a really accurate location, which is very possible.
Have you set desiredLocationAccuracy in your CLLocationManager? By default the range is somewhat wide.
It will take some time to acquire a very exact value.
I have a scenario where i search for the current location.Once the current location search begins i use "startMonitoringSignificantLocationChanges" i get didUpdateToLocation delegate called and i get a location value.
After the search is over i use "stopMonitoringSignificantLocationChanges" to turn off the GPS.
My problem is i may to the surrent location search after some time,when its done that is when i again start searching for current location after sometime GPS turns on but "didUpdateToLocation" is not called.
I am doing all these in a view controller.
I have initialized the location manager and have set the desiredAccuracy to "kCLLocationAccuracyNearestTenMeters" and distanceFilter to "10.0f".
Why i am not able to call "didUpdateToLocation" delegate on stooping the location updates and starting it again.
Please any body help me...
Expecting for a positive response from any of you.
Thank you.
You should use startUpdatingLocation instead of startMonitoringSignificantLocationChanges. startMonitoringSignificantLocationChanges calls didUpdateToLocation only when location is significantly changed.
if (locationManager == nill)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
locationManager.distanceFilter = 10;
[locationManager startUpdatingLocation];
Sometimes I receive the wrong value for my current location, an error of up to 2 miles. Am I doing everything correctly?
self.myLocation = [[CLLocationManager alloc] init];
myLocation.delegate = self;
myLocation.desiredAccuracy = kCLLocationAccuracyBest;
[myLocation startUpdatingLocation];
What's the most accurate method to receive GPS location?
You get a stream of location updates from the device when you start monitoring location change and so you need to consider both the timestamp of the location update and its horizontal accuracy.
Use the timestamp to reject old values (for example when you first start monitoring, you will be sent an accurate (at the time) but old cached value).
Use the horizontal accuracy to reject values that are outside of your desired range.