CLLocationManager holds cache value

2019-06-06 18:03发布

This part of code of CLLocationManager is used to calculate the distance travelled. But the location cache is not removed even after using timeIntervalSinceNow.

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {


    if(newLocation != nil && oldLocation != newLocation)
    {
        tempNewLocation = newLocation;
        tempOldLocation = oldLocation;
    }



    NSLog(@"New Location Found");
    NSLog(@"- Latitude: %f", newLocation.coordinate.latitude);
    NSLog(@"- Longitude: %f", newLocation.coordinate.longitude);
    NSLog(@"- Altitude: %f", newLocation.altitude);
    NSLog(@"- Course: %f", newLocation.course);

    NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
    NSLog(@"The location age %f",locationAge);
    if (locationAge > 2.0) 
    {
    }
    else
    {
if (tempOldLocation.coordinate.latitude == tempNewLocation.coordinate.latitude   && tempNewLocation.coordinate.longitude == tempOldLocation.coordinate.longitude) 
{
    NSLog(@" Fix location found ");
}
else
{
    if(tempNewLocation.coordinate.latitude == tempOldLocation.coordinate.latitude && tempNewLocation.coordinate.longitude == tempOldLocation.coordinate.longitude)
    {
        NSLog(@"First Time Location Update");
        latitudeLongitude.text = [[ NSString alloc] initWithFormat:@"%g , %g", tempNewLocation.coordinate.latitude, tempNewLocation.coordinate.longitude];


        totalDistance =  0;
        distance.text = @"0 miles";
    }
    else if ([tempNewLocation distanceFromLocation:tempOldLocation] - tempNewLocation.horizontalAccuracy >= 0) 
    {

    totalDistance +=  [tempNewLocation distanceFromLocation:tempOldLocation] - (tempNewLocation.horizontalAccuracy / 2);
}
else{


    totalDistance +=  [tempNewLocation distanceFromLocation:tempOldLocation];
}



 if (totalDistance < 0) {
        distance.text = @"0 miles";

    }
    else
    milesdistance=0.000621371192*totalDistance;



distance.text = [[ NSString alloc] initWithFormat:@"%.1f", milesdistance];


odometerreading.text = [NSString stringWithFormat:@"%09.1f", milesdistance];
mileagerate.text = [[NSUserDefaults standardUserDefaults] valueForKey:@"savedstring"];


float mileagefloat=[self.mileagerate.text floatValue];
amount.text =  [NSString stringWithFormat:@"%.2f",mileagefloat * milesdistance];
amountstatus.text=[NSString stringWithFormat:@"$%.2f",mileagefloat * milesdistance];
newnumber=totalDistance;



}

This code doesnt work for me, and when I start tracking, distance is calculated from the place where I last stopped the tracking.

NSTimeInterval locationAge = -[newLocation.timestamp timeIntervalSinceNow];
        NSLog(@"The location age %f",locationAge);
        if (locationAge > 2.0) 

4条回答
兄弟一词,经得起流年.
2楼-- · 2019-06-06 18:44

I found the answer for removing cache. For the first time didUpdateToLocation is called, the newlocation fetches the cache value, and the old location is null. And in the second call, newlocation value is swapped to oldlocation and the newlocation is updated. And hence to get the updated value, the function has to be called twice.

- (void)locationManager:(CLLocationManager *)manager 
        didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {

        static CLLocation *locationanalysis1;
    NSLog(@"New Location Found");
    NSLog(@"- Latitude: %f", newLocation.coordinate.latitude);
    NSLog(@"- Longitude: %f", newLocation.coordinate.longitude);
    NSLog(@"- Altitude: %f", newLocation.altitude);
    NSLog(@"- Course: %f", newLocation.course);

    NSDate *eventDate = newLocation.timestamp; 
    NSTimeInterval howRecent = -[eventDate timeIntervalSinceNow];
    if (howRecent > maximumElapsedTimeForCachedLocation)  {             

            locationanalysis1=newLocation;

        return;
}


    if((locationanalysis1.coordinate.latitude-oldLocation.coordinate.latitude)==0){
        NSLog(@"Old Location in location analysis is %@",oldLocation);


      return;
    }

    NSLog(@"New location accuracy %.0fm", newLocation.horizontalAccuracy);
    if ((newLocation.horizontalAccuracy < 0) || (newLocation.horizontalAccuracy > 10)) return;
    if(oldLocation!=NULL && newLocation!=NULL){

                totalDistance +=  [newLocation distanceFromLocation:oldLocation];
    }else return;
}
查看更多
混吃等死
3楼-- · 2019-06-06 18:46

I use a counter that counts how many times didUpdateToLocation is called.
I only use the location received after at least 3 calls.

I know 3 is a magic number but i have found that the first 3 calls are cache or very inaccurate.

查看更多
▲ chillily
4楼-- · 2019-06-06 18:51

Take a look at the answer to this question, as it includes code from Apple's sample app "LocateMe" and provides a bit more detail as to what you are trying to do:

https://stackoverflow.com/a/12848776/346098

查看更多
乱世女痞
5楼-- · 2019-06-06 19:01

You want to check the timestamp property of the new CLLocation object in your delegate method. By the sounds of it are only interested in lat/long that are no older than XXX seconds.

NSTimeInterval timeInSeconds = [newLocation.timestamp timeIntervalSinceNow];
if (timeInSeconds > YOUR_CUSTOM_TIME_IN_SECONDS)
{
    // Do something
}
查看更多
登录 后发表回答