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

Iphone 调用了didUpdateLocations,但发送了错误的位置,iphone,ios,objective-c,Iphone,Ios,Objective C,我使用核心位置来获取iphone的位置。我还实现了viewcontroller文件的委托协议,并创建了一个CLLocationmanager对象 当我按下按钮(iAction)时,我希望位置得到更新。正确调用委托。我可以看到这一点,因为NSLog消息以lat/long坐标显示 但是,当我在IOS模拟器中更改位置并尝试使用按钮再次访问该位置时,我得到的位置输出保持不变。我得再按一下按钮才能找到正确的位置。显然,我希望第一次按下按钮时位置正确 这是触发代理的我的按钮: - (IBAction)get

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

当我按下按钮(iAction)时,我希望位置得到更新。正确调用委托。我可以看到这一点,因为NSLog消息以lat/long坐标显示

但是,当我在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模拟器中运行我的代码。

我想,在您的Xcode中已经设置了一个不同的位置作为模拟位置,这就是模拟器向您展示的内容。先看看。模拟器不会显示您的当前位置,而是显示在Xcode中设置为模拟位置的位置。只有设备才能显示您的真实位置。希望能有所帮助。

这可能是因为您试图从内部更新UI
didUpdateLocations
,它肯定运行在主线程以外的另一个线程上

更改此项:

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];
    });
}

在iOS6中尝试这段代码。苹果希望我们使用didUpdateLocation而不是didUpdateLocation

.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];

}

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

多亏了下面的注释和其他答案,我找到了答案

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


所以我只是在使用NSTimer执行StopUpdateLocation之前等待。成功了。谢谢gWiz

来自苹果参考:

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

在另一个stack overflow post()中也回答了这个问题,使用CLLocation的timestamp属性过滤掉返回的旧的缓存位置对象。我选择了15秒来确保区分缓存对象,但即使只有几秒也可能足够:

NSTimeInterval timeInterval = [[location timestamp] timeIntervalSinceNow];
if (abs((NSInteger)timeInterval) < 15)
{
    //do something
}
NSTimeInterval timeInterval=[[location timestamp]timeIntervalSinceNow];
if(绝对值((NSInteger)时间间隔)<15)
{
//做点什么
}

这不是位置管理器显示伪造位置的原因,但它也可能有助于更新位置UI@harrym17问题似乎只是UI更新,因为第二次按下按钮时会显示正确的位置。谢谢,但这不会改变任何事情。仍然需要按两次“获取位置”按钮才能获取我将其更改为的位置。请尝试执行
NSLog(@“%@”,“NSString stringWithFormat:@“%.8f”,currentLocation.coordinate.longitude])并查看您得到了什么,只是为了确保这不是一个UI问题。我认为这不仅仅是一个UI更新问题。因为日志消息也是错误的。当我更新位置时,我的程序会弹出一条日志消息,但lat/long坐标与前一个位置相同。只有在我第二次按下按钮时,日志消息才会更改。只是一条注释,在目标C中,您可以键入if(currentLocation)而不是if(currentLocation!=nil)。这是因为您只在按下按钮时开始更新位置,并在获得第一个位置后停止(第一个位置可能不是最准确的)。您应该让locationManager不断更新位置。这不是问题所在。我知道我在模拟器中输入的位置是假的。问题是,当我改变这个模拟地点并通过startUpdating方法更新我的地点时,地点不会随之改变,然后说你从纽约换到了伦敦。第一次按下后显示什么?第二次之后呢?如果它没有更新,那么尝试重新启动Xcode,它应该可以工作。重新启动Xcode不起作用。当我第一次从纽约换到伦敦时,它仍然显示纽约坐标。第二次坐标正确更新到伦敦时,如果用户更改设备的日期和时间,此解决方案将不起作用