didUpdateLocations 被调用,但发送错误的位置
Posted
技术标签:
【中文标题】didUpdateLocations 被调用,但发送错误的位置【英文标题】:didUpdateLocations gets called, but sends wrong location 【发布时间】:2013-10-14 15:23:24 【问题描述】:我正在使用核心位置来获取 iphone 的位置。我还为我的视图控制器文件实现了委托协议,并创建了一个 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 模拟器中运行我的代码..
【问题讨论】:
只是一个注释,在 Objective C 中你可以输入 if(currentLocation) 而不是 if (currentLocation != nil)。 这是因为你只有在按下按钮时才开始更新位置,并在获得第一个位置后停止(第一个位置可能不是最准确的)。您应该保持 locationManager 更新位置。 【参考方案1】:来自 Apple 参考资料:CLLocationManager
由于返回初始位置可能需要几秒钟,因此位置管理器通常会立即提供先前缓存的位置数据,然后在可用时提供更多最新的位置数据。
还在另一个堆栈溢出帖子 (https://***.com/questions/12858548/cllocationmanager-holds-cache-value) 中回答,使用 CLLocation 的时间戳属性过滤掉返回的较旧的缓存位置对象。我选择了 15 秒来确保区分缓存对象,但即使只有几秒钟也可能就足够了:
NSTimeInterval timeInterval = [[location timestamp] timeIntervalSinceNow];
if (abs((NSInteger)timeInterval) < 15)
//do something
【讨论】:
如果用户更改设备的日期和时间,此解决方案将不起作用【参考方案2】:我想通了,感谢下面其他答案的 cmets..
我在调用[locationManager stopUpdatingLocation];
方法之前等待的时间太短了。 GPS 只是需要更多时间..
所以我只是在使用 NSTimer 执行 stopUpdatingLocation 之前等待。那完成了工作。感谢 gWiz!
【讨论】:
【参考方案3】:我认为,已经在您的 Xcode 中设置了一个不同的位置作为模拟位置,这就是模拟器向您显示的内容。先检查一下。模拟器不会显示您当前的位置,它会显示在 Xcode 中设置的位置作为模拟位置。只有设备可以显示您的真实位置。希望对您有所帮助。
【讨论】:
这不是问题。我知道我在模拟器中输入的位置是假的。问题是当我更改这个模拟位置并通过 startUpdating 方法更新我的位置时,位置不会随之改变 然后说你从纽约到伦敦。第一次按下后显示什么?在第二个之后? 如果它没有更新,然后尝试重新启动 Xcode ,它应该可以工作。 重启 Xcode 不起作用。当我第一次从纽约换到伦敦时,它仍然显示纽约坐标。第二次坐标正确更新到伦敦【参考方案4】:这可能是因为您尝试从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];
);
【讨论】:
这不是位置管理器显示伪造位置的原因,但它也可能有助于更新 UI @harrym17 问题似乎只是 UI 更新,因为第二次按下按钮时会显示正确的位置。 谢谢,但这并没有改变任何东西。仍然需要按两次“获取位置”按钮才能获取我更改的位置。 尝试NSLog(@"%@", [NSString stringWithFormat:@"%.8f", currentLocation.coordinate.longitude]);
看看你得到了什么,以确保这不是 UI 问题。
我认为这不仅仅是一个 UI 更新问题。因为日志消息也是错误的。当我更新位置时,我的程序会输出一条日志消息,但纬度/经度坐标与之前的位置相同。只有在我第二次按下按钮时,日志消息才会更改。【参考方案5】:
在 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];
【讨论】:
【参考方案6】:CLLocationManager 会缓存您的位置数据。 一个有用的方法是检查更新之间的时间间隔。 您将获得每个位置更新的时间戳。 使用此比较旧的和新的位置时间戳 [newLocation.timestamp timeIntervalSinceDate:oldLocation.timestamp] 如果间隔大于 5 左右,则丢弃这些更新。
【讨论】:
以上是关于didUpdateLocations 被调用,但发送错误的位置的主要内容,如果未能解决你的问题,请参考以下文章
iOS - CLLocation Manager didUpdateLocations 在一个类中被调用,而不是在另一个类中?
不能调用 locationManager(_::didUpdateLocations:)
监视重大位置更改时不会调用“didUpdateLocations”