My first location using Core Location is almost always invalid.
My code is as follows:
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
//for saving the data ACCURATELY for calculations
// make sure the coordinates are valid
if ([self isValidLocation:newLocation withOldLocation:oldLocation])
{
mDistance = [newLocation distanceFromLocation:oldLocation];
[[NSNotificationCenter defaultCenter]postNotificationName:@"locationUpdated" object:nil];
}
}
As you can see it checks to see if it is a valid location with isValidLocation. That code is here:
- (BOOL)isValidLocation:(CLLocation *)newLocation
withOldLocation:(CLLocation *)oldLocation
{
// Throw away first point
if (isFirstPoint)
{
NSLog(@"First point thrown away.");
isFirstPoint = NO; //subsequent updates will NOT be the first point
return NO;
}
// Filter out nil locations
if (!newLocation){
NSLog(@"New location invalid");
return NO;
}
if (!oldLocation)
{
NSLog(@"Old location invalid");
return NO;
}
// Filter out points by invalid accuracy
if (newLocation.horizontalAccuracy < 0)
{
return NO;
}
// Filter out points that are out of order
NSTimeInterval secondsSinceLastPoint = [newLocation.timestamp
timeIntervalSinceDate:oldLocation.timestamp];
if (secondsSinceLastPoint < 0){
return NO;
}
// Filter out points created before the manager was initialized
NSTimeInterval secondsSinceManagerStarted = [newLocation.timestamp
timeIntervalSinceDate:locationManagerStartDate];
if (secondsSinceManagerStarted < 0){
return NO;
}
// If the distance is negative
if ([newLocation distanceFromLocation:oldLocation] < 0)
{
return NO;
}
if(newLocation.speed < 0)
{
return NO;
}
// GIANT ELSE: The newLocation is good to use
return YES;
}
Even after checking all of that, my first point is always invalid. For example, I went from work to home, and turned on my location manager at home, yet my first coordinate was from my office at work. How can I fix this?
Here is what happens when I get an invalid first point:

It really depends on your use case. Core Location often returns the device’s last known position in order to give you a result as quickly as possible. This location is passed to you before the device has finished acquiring a new location. The last known position can be several kilometers off your current position.
Depending on the type of your app, this might be a totally negligible difference (e.g. if an app just wants to locate the country a user is in) or it might represent an inacceptable error. Core Location can’t tell.
It’s important for you to decide how to deal with this behavior. Always throwing the first reported location away might not be the best strategy. You might want to store the time when you call
startUpdatingLocationand only throw the first reported location away if the system passes it to you within a very brief period of time (say, 1/10th of a second) that makes it likely to be a cached location. Also, the location’stimestampproperty might be helpful in judging how (in)accurate the reported location can be.