调用didUpdateLocations,但发送错误的位置

时间:2013-10-14 15:23:25

标签: iphone ios objective-c

我正在使用核心位置来获取iPhone的位置。我还为我的viewcontroller文件实现了委托协议,并创建了一个CLLocationmanager对象..

当我按下按钮(IBAction)时,我想要更新位置。委托被正确调用。我可以看到,因为NSLog消息显示为纬度/经度坐标。

但是当我在IOS模拟器中更改位置并尝试使用按钮再次访问该位置时,我得到的位置输出保持不变。我必须再次按下按钮才能获得正确的位置。显然,我希望第一次按下按钮时位置正确

这是触发委托的按钮:

- (IBAction)getLocation:(id)sender {


[locationManager startUpdatingLocation];
}

我在viewDidLoad中有这段代码

locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters;

这是我的委托方法:

#pragma mark - CLLocationManagerDelegate 
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(@"didFailWithError: %@", error);
UIAlertView *errorAlert = [[UIAlertView alloc]
                           initWithTitle:@"Error" message:@"Failed to Get Your Location" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
[errorAlert show];
 }

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations{
NSLog(@"didUpdateToLocation: %@", [locations lastObject]);
CLLocation *currentLocation = [locations lastObject];


if (currentLocation != nil) {
    _longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
    _latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
   }
[locationManager stopUpdatingLocation];
}

我在Iphone 6.1模拟器中运行我的代码..

6 个答案:

答案 0 :(得分:4)

来自Apple参考:CLLocationManager

  

由于返回初始位置可能需要几秒钟,因此位置管理员通常会立即提供以前缓存的位置数据,然后在可用时提供更多最新的位置数据。

另外在另一个堆栈溢出帖子(https://stackoverflow.com/questions/12858548/cllocationmanager-holds-cache-value)中回答,使用CLLocation的timestamp属性来过滤掉返回的旧缓存位置对象。我选择15秒来确保区分缓存的对象,但即使只有几秒钟也可能就足够了:

NSTimeInterval timeInterval = [[location timestamp] timeIntervalSinceNow];
if (abs((NSInteger)timeInterval) < 15)
{
    //do something
}

答案 1 :(得分:1)

我想通了,感谢下面其他答案的评论..

在调用[locationManager stopUpdatingLocation];方法之前,我等待的时间太短了。 GPS需要更多的时间..

所以我在使用NSTimer执行stopUpdatingLocation之前等待。这样做了。感谢gWiz!

答案 2 :(得分:0)

我认为,在Xcode中设置了一个不同的位置作为模拟位置,这就是模拟器向您显示的内容。先检查一下。模拟器不会显示您当前的位置,它会将在Xcode中设置的位置显示为模拟位置。只有设备才能显示您的真实位置。希望它有所帮助。

答案 3 :(得分:0)

这可能是因为您正在尝试从didUpdateLocations内部更新UI,这肯定会在主线程之外的另一个线程上运行。

改变这个:

if (currentLocation != nil) {
_longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
_latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
}

到此:

if (currentLocation != nil) {
    dispatch_async(dispatch_get_main_queue(), ^{
        _longitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude];
        _latitudeLabel.text = [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.latitude];
    });
}

答案 4 :(得分:0)

在iOS6中试用此代码Apple希望我们使用didUpdateLocations而不是didUpdateToLocation

.h file


    CLLocationManager *locationManager;


.m File

  // get the current location latitude and longitude

    // locationManager update as location
    locationManager = [[CLLocationManager alloc] init];
    locationManager.delegate = self;
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    [locationManager startUpdatingLocation];

    CLLocation *location = [locationManager location];


    locationManager.delegate=self;

    //Get user location
    [locationManager startUpdatingLocation];

    // Configure the new event with information from the location
    CLLocationCoordinate2D coordinate = [location coordinate];

    NSString *latitude = [NSString stringWithFormat:@"%f", coordinate.latitude];
    NSString *longitude = [NSString stringWithFormat:@"%f", coordinate.longitude];

    NSLog(@"dLatitude : %@", latitude);
    NSLog(@"dLongitude : %@",longitude);


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

[locations lastObject];

}

答案 5 :(得分:0)

CLLocationManager会缓存您的位置数据。 一种有用的方法是检查更新之间的时间间隔。 您将获得每个位置更新的时间戳。 使用此比较旧位置时间戳和新位置时间戳 [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp]并在interval大于5的情况下丢弃这些更新。