문제

In my app I'm comparing two locations. One is the actual location and the other is a fixed one. I set the second location by a button. When a certain distance is covered I'm prompted with an alertView. By tapping the stop butten the locationmanager stops. The problem is when I want to start again the app uses the location on wich I tapped the stop button, and not a new one. I've tried to rule the cache out by using a NSTimeInterval but I'm still getting the last "known" position. Please help.

Here is my code (in two methods)

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

eventDate = newLocation.timestamp;

NSLog (@"eventDate from locmanager %@", eventDate);

NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
[formatter setNumberStyle:NSNumberFormatterDecimalStyle];
NSString *groupingSeparator = [[NSLocale currentLocale] objectForKey:NSLocaleGroupingSeparator];
[formatter setGroupingSeparator:groupingSeparator];
[formatter setGroupingSize:3];
[formatter setAlwaysShowsDecimalSeparator:NO];
[formatter setUsesGroupingSeparator:YES];


//display latitude
NSString *lat =[[NSString alloc]initWithFormat:@"%f",
                newLocation.coordinate.latitude];
latitude.text=lat;

//display longitude
NSString *lon = [[NSString alloc]initWithFormat:@"%f",
                 newLocation.coordinate.longitude];
longitude.text=lon;

//display accuracy
accuracy.text = [formatter stringFromNumber:[NSNumber numberWithFloat:newLocation.horizontalAccuracy]];


double actLat = [[latitude text]doubleValue];
int latSeconds = actLat * 3600;
int latDegrees = latSeconds / 3600;
latSeconds = abs(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;

NSString *latStringLocal = NSLocalizedString((actLat > 0) ? @"North" : @"South", @"");

double actLon = [[longitude text]doubleValue];
int lonSeconds = actLon * 3600;
int lonDegrees = lonSeconds / 3600;
lonSeconds = abs(lonSeconds % 3600);
int lonMinutes = lonSeconds / 60;
lonSeconds %= 60;

NSString *lonStringLocal = NSLocalizedString((actLon > 0) ? @"East" : @"West", @"");

NSString *actPosWord = NSLocalizedString (@"WordActual", @"");
NSString *actPosition = [[NSString alloc]initWithFormat:@"%@ %i° %i' %i\" %@" "   " @"%i° %i' %i\" %@", actPosWord, latDegrees, latMinutes, latSeconds, latStringLocal,lonDegrees, lonMinutes, lonSeconds, lonStringLocal];

_actualPosition.text = actPosition;

[self distanceFromLocation];

}

and the second one to refresh the "fixed" position:

-(void)recordLocation{

NSDate* timeNow = [NSDate date];

NSLog (@"eventDate from recordLocation %@", eventDate);
    if ([timeNow timeIntervalSinceDate:eventDate] > 2.0f)

{

double valueLat = [[latitude text]doubleValue];
int latSeconds = valueLat * 3600;
int latDegrees = latSeconds / 3600;
latSeconds = abs(latSeconds % 3600);
int latMinutes = latSeconds / 60;
latSeconds %= 60;

NSString *latStringLocal = NSLocalizedString((valueLat > 0) ? @"North" : @"South", @"");

double valueLon = [[longitude text]doubleValue];
int lonSeconds = valueLon * 3600;
int lonDegrees = lonSeconds / 3600;
lonSeconds = abs(lonSeconds % 3600);
int lonMinutes = lonSeconds / 60;
lonSeconds %= 60;

NSString *lonStringLocal = NSLocalizedString((valueLon > 0) ? @"East" : @"West", @"");

tempPos = [[CLLocation alloc] initWithLatitude:valueLat longitude:valueLon];

NSString *watchedPosWord = NSLocalizedString (@"WordWatched", @"");
NSString *recPosition = [[NSString alloc]initWithFormat:@"%@ %i° %i' %i\" %@" "   " @"%i° %i' %i\" %@ \n", watchedPosWord, latDegrees, latMinutes, latSeconds, latStringLocal,lonDegrees, lonMinutes, lonSeconds, lonStringLocal];

_labelDegrees.text = recPosition;

//create region for ovelay

double areaWatched = [[watchedArea text] doubleValue];

MKCoordinateRegion region;
region.center.latitude = valueLat;
region.center.longitude = valueLon;
region.span.latitudeDelta = 0.001f;
region.span.longitudeDelta = 0.001f;
region.center = tempPos.coordinate;
[self.mapView setRegion:region animated:YES];

MKCircle *circle = [MKCircle circleWithCenterCoordinate:region.center radius:areaWatched];

[self.mapView addOverlay:circle];
}

}
도움이 되었습니까?

해결책 3

Because of the structure of my app (need locations in two methods) NSTimeinterval with teh abs() statement didn't work. It mau tell more about me as of the provided answer but my solution was a NSTimer statement in my Activat method. With a delay of 0.1 seconds it works perfectly. For anyone interested, her's my code:

- (IBAction)Activate:(UIButton *)sender {
[self startUpdatingLocation];
[self.mapView setUserTrackingMode:MKUserTrackingModeFollow animated:YES];
[mapView setCenterCoordinate:mapView.userLocation.location.coordinate animated:YES];
i = 1;
[NSTimer scheduledTimerWithTimeInterval:0.1
                                 target:self
                               selector:@selector(recordLocation)
                               userInfo:nil
                                repeats:NO];

}

다른 팁

You get a cached location because the OS is just saving time and energy. You need to implement your own filter in -didUpdateToLocation. This method will get called every second until you call -stopUpdatingLocation. I would build your code around letting this method be called until you are happy with the location timestamp and/or accuracy. The longer it runs, the more accurate the location will be. It also means that the GPS runs more and can negatively affect battery if left running too long.

Create a property, such as @property (nonatomic, retain) CLLocation *currentLocation; and use it to store the last position got by the location manager. It's also important to verify if the location manager is not sending cached positions, like this:

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

    //if the time interval returned from core location is more than two minutes we ignore it because it might be from an old session
    NSDate *eventDate = newLocation.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];

    if ( abs(howRecent) < 15.0 )
    {

        self.currentLocation = newLocation;
        // do whatever you have to do
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top