我在Objective C中遇到问题(为iPhone编写应用程序)。我知道如何使用locationManager
及其代理人。在startUpdatingLocation
上调用locationManager
后,只要位置更新,它就会调用委托方法didUpdateToLocation
。但问题是,这种方式现在适合我想做的事情。我有一个方法(在类中),如下所示:
@implementation SomeClass
- (someType)getDbContentsOrderByDistance
{
... //here I need the current location
return dbContents;
}
@end
现在,此函数从sqlite数据库中选择按其与用户当前位置的距离排序的条目。这就是为什么我需要这个功能的位置。我想在上面的方法中做的是:获取位置,然后从数据库中选择东西并返回它。我知道我可以尝试访问locationManager.location.coordinate.longitude
,但我知道在第一个位置更新到来之前内部没有任何有用的东西。而且我不想在之前启动位置更新(例如,在启动应用程序时),因为如果我只需要一次该位置,这将不会非常有效。
我知道如何在位置更新到达时立即调用委托的方式。问题是我不知道如何从那里获得更新的位置到上面的方法。基本上我需要让方法“等待”,直到第一个位置更新,然后继续执行该位置。
感谢您的帮助!
答案 0 :(得分:1)
启动一个每秒钟左右触发的计时器,调用您需要该位置的功能。检查位置是否已设置。如果该位置有效则杀死计时器,如果没有,则让计时器继续并在一秒左右再次检查。
知道位置是否有效的方法是在委托方法中。设置像locationAvailable = false
这样的全局变量。然后,当委托方法被调用时,将该变量设置为true。
答案 1 :(得分:1)
简短的回答是,你不能。获取用户位置是一个异步过程,必须是一个异步过程。该设备必须启动各种硬件,如GPS,手机信号塔定位器和WiFi三角测量系统,从这些不同的设备获取输入,并将其合成到一个位置。这需要几秒钟的时间。
普茨关于启动计时器的建议很好。我会添加一些东西。通常,您从位置管理器获得的第一个读数非常糟糕,应该被丢弃。您获得的第一个读数通常是GPS处于活动状态时读取的最后位置,并且将具有过时的时间戳。该位置的准确度读数可能看起来很不错,但这只是一个谎言。我已经看到第一个位置读数偏离了几公里。您需要检查位置更新的时间戳,并丢弃任何超过1秒的读数。
一旦您丢弃了陈旧的读数,前几次位置更新通常都非常糟糕,因为GPS还没有安定下来。水平精度读数(实际上是混淆圈和#34;或可能位置的半径)是一个荒谬的大值,有时是一公里或更多。同样,您需要编写您的位置管理器委托方法以丢弃过于不准确的读数。我建议丢弃水平精度读数≥100米的值。您可以容忍多少不准确取决于具体的称谓,但要注意使准确度要求过于准确。有时GPS拒绝安定下来。如果您需要5米的精度,则在整个应用程序运行期间可能无法获得可接受的准确度。 (如果您在城市环境,建筑物或其他存在大量干扰/阻碍GPS信号的区域)
一旦你最终得到一个足够准确的值,保存位置并将locationAvailable标志设置为YES。
请注意,您可以使用通知管理器代替计时器来广播"获得一个好位置"信息。任何需要位置信息的对象都可以注册您的通知,并在位置管理器获得可接受的位置读数时被调用。
答案 2 :(得分:0)
使用location属性可以解决目的
From apple documentation 位置最近检索到的用户位置。 (只读) @property(只读,非原子,复制)CLLocation *位置
如果从未检索过任何位置数据,则此属性的值为nil。 在iOS 4.0及更高版本中,此属性可能在启动时包含更新的位置对象。具体而言,如果正在运行重要的位置更新且您的应用已终止,则会在重新启动应用时使用最新的位置数据更新此属性(并创建新的位置管理器对象)。此位置数据可能比您的应用处理的最后一个位置事件更新。 检查存储在此属性中的位置的时间戳始终是一个好主意。如果接收器当前正在收集位置数据,但最小距离过滤器很大,则返回的位置可能相对较旧。如果是,您可以停止接收器并再次启动以强制更新。
每当我创建一个新的位置管理器实例时,我会在 位置 属性中获取最新的位置值,并且因为我的距离过滤器未设置,所以它具有当前值时间戳。这意味着我不必调用startUpdatingLocation并且我的数据是准确的。我还需要这个来计算用户位置和地点之间的距离,这样如果它在范围内,我可以立即返回true或false。我发现这非常有用,因为我在0.006秒内得到位置并且方便并且仅从苹果文档获得它但仍然不知道它是否是最佳实践。