I was doing gps location by using CLLocation. When i press submit button and start the process to get the coordinate. However the locationManager being called multiple times.
How can I get the value from last called in locationManager function ?
Thanks
locationManager.location will give you the most recently retrieved location if it exists, otherwise the value will be nil.
Related
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];
when i try to get the current location using
CLLocationCoordinate2D CurrentLocation;
CurrentLocation = map.userLocation.coordinate;
i get the follwoing values:
CurrentLocation.latitude= -180.000000;
CurrentLocation.longitude= -180.000000;
and it is not my location at all.
do you know what is missing in this?
Firstly, make sure that you have set the mapView's showUserLocation to TRUE.
Secondly, check that the value is not nil, as the mapView needs to locate the user first, and that takes a few seconds.
time to time there is an issue with geting the location coordinate on my app.
I have been testing my app for location coordinate from the simulator and the iphone sitting at my home (it is not just my home, i tested it in different location (outdoor) as well with a very good network connectivity), and i see this wired behavior, i have the right co ordinate at the moment and then i send the app to the background and bring it back i get the right location co ordinate, and if i do it 8-10 times (i.e sending it to background and bringing it to foreground) once in a while after the app comes from the background i cannot get location co ordinate, the only way to get the location co ordinate at this moment is to kill the app and then start fresh. So i am sure some thing is going wrong but I am not sure what is it.
This is what I am doing
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
//if the time interval returned from core location is more than 30 seconds we ignore it because it might be from an old session
if ( abs([newLocation.timestamp timeIntervalSinceDate: [NSDate date]]) < 30) {
if(newLocation.coordinate.latitude != previousLocation.coordinate.latitude && newLocation.coordinate.longitude != previousLocation.coordinate.longitude){
if(newLocation.horizontalAccuracy <= 100){
[self.locationManager stopUpdatingLocation];
[self.locationManager startMonitoringSignificantLocationChanges];
}
else{
[self.locationManager startUpdatingLocation];
}
So basically i take the newLocation only if it is not older then 30 sec, and it is not same as previous location that i have stored locally and the horizontal accuracy is less than 100 meter. When i run it in debugger what i am observing is i get to the first if condition 3-4 times and if it fails it doesn't come after that, which means didUpdateToLocation doesn't get called at all.
Once the co ordinate meet all my criteria I do stopupdatinglocation and do startMonitoringSignificantLocationChanges.
The reason i am doing startUpdatingLocation in my else block is.
For example if didUpdateToLocation got called due to the startMonitoringSignificantLocationChanges, i want to get the accurate location after that so i am doing startUpdatingLocation every time i don't get the right location that i am looking for as i believe doing multiple startUpdatingLocation doesn't harm anything.
Let me know if there is something wrong in my thought process or in the code logic.
The first thing I would check is your info.plist. You have to include the key Required Background Modes -> App registers for location updates. Without this you won't receive location updates (besides significant location changes and region monitoring) while in the background.
In the main else, you call startUpdatingLocation. While I don't believe this hurts anything, unless you are balancing it with a stopUpdatingLocation I don't believe it will do anything. Documentation says:
Calling this method several times in succession does not automatically result in new events being generated. Calling stopUpdatingLocation in between, however, does cause a new initial event to be sent the next time you call this met
But either way, I don't think you need to tell it to startUpdating again, it will continue on it's own when the distanceFilter property is exceeded or the hardware gathers a more accurate location reading.
I don't see a closing } for your second if.
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.
I am wondering if there is some way to make it so CLLocationManager doesn't automatically returned a cached location. I understand that the documents say "The location service returns an initial location as quickly as possible, returning cached information when available" but this cached location could be extremely far away from the user's current location and I would like it more precise if possible.
Thanks for any help!
You can't stop it from caching, but it's not hard to filter out cached data. Core Location includes a timestamp with its locations. Compare the timestamp of the location with a timestamp saved when your app started, and you'll be able to tell which locations are old (cached, found before your app stated) and which are new. Throw away the old ones.
The location timestamp is an NSDate, so just get the value of [NSDate date] when your app starts up and use that as your reference point when filtering locations. You could even throw away the reference value once you start getting new data and treat a nil reference date as implying that new locations should be trusted.
-(void)locationManager:(CLLocationManager*)manager didUpdateToLocation:(CLLocation*)newLocation fromLocation:(CLLocation *)oldLocation
{
if ([newLocation.timestamp timeIntervalSinceNow] > -10.0) // The value is not older than 10 sec.
{
// do something
}
}
You can use this property of CLLocationManager:
#property(readonly, NS_NONATOMIC_IPHONEONLY) CLLocation *location;
The value of this property is nil if no location data has ever been retrieved, otherwise, this is where CoreLocation caches its data. Therefore, if you always want to start from scratch, simply check if this property is nil or not. If it's nil, then you are ok; otherwise, you need to stop your location manager and start it again: this will force an update, which will result in the cached value being overwritten by the fresh one you have just triggered.