Swift CLLocation 在启动时不更新位置
Swift CLLocation does not update location at startup
我有一个应用程序,我想在 viewDidLoad 中获取用户位置,然后我将纬度和经度存储在变量中,并在函数中使用它们以根据用户的位置获取数据。我有一个计时器,每 x 分钟调用一个函数来获取数据(我们称之为 getData()),第一次调用 getData() 时经纬度为 0,但第二次、第三次等。他们有值。
当我在模拟器中更新坐标(在 运行 时间内)时,我确实得到了经纬度的更新值,但它是第一个 运行 纬度和经度总是是 0。我的代码如下所示:
let locationManager = CLLocationManager()
var getDataGroup = dispatch_group_create()
override func viewDidLoad() {
super.viewDidLoad()
dispatch_group_enter(getDataGroup)
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
dispatch_group_leave(getDataGroup)
dispatch_group_wait(getDataGroup, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_main_queue()) {
self.getData()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
if (error != nil){
println("Error: " + error.localizedDescription)
return
}
if (placemarks.count > 0){
let pm = placemarks[0] as! CLPlacemark
self.displayLocationInfo(pm)
}
else{
println("Error with location data")
}
})
}
func displayLocationInfo (placemark : CLPlacemark){
self.locationManager.stopUpdatingLocation()
lat = String(stringInterpolationSegment: placemark.location.coordinate.latitude)
long = String(stringInterpolationSegment: placemark.location.coordinate.longitude)
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Error: " + error.localizedDescription)
}
func getData(){
// Do stuff with lat and long...
}
出于某种原因,第一个 运行 lat 和 long 均为 0,其余 运行s 它们具有有效值。问题是 getData 在 locationManager 和 displayLocationInfo 方法之前被调用,即使我出于某种原因在调用 getData() 之前添加了 self.locationManager.startUpdatingLocation()。
我不太明白你的代码应该做什么。
您的 viewDidLoad 中没有 GCD 代码的原因。只需创建位置管理器的实例并告诉它开始更新您的位置。
一旦位置可用,就会调用您的 didUpdateLocations 方法。使用您在该方法中获得的位置数组中的最后一个位置 - 这将是最近的。
我建议在使用之前检查位置的 horizontalAccuracy。通常前几个位置读数非常糟糕,然后读数慢慢稳定下来。水平精度读数实际上是给出读数可能区域的半径。如果你得到 1 公里,这意味着你的位置可以在半径为 1 公里的圆圈内的任何地方。您可能想要丢弃那么差的读数,等待几百米以内(或更远)的读数。
您的 viewDidLoad 方法正在调用方法 getDeparturesAtStop,并且该方法可能会在第一次调用 didUpdateLocations 触发之前被调用。 (您没有显示该方法的作用。)
获得零的代码在哪里 lat/long?
我有一个应用程序,我想在 viewDidLoad 中获取用户位置,然后我将纬度和经度存储在变量中,并在函数中使用它们以根据用户的位置获取数据。我有一个计时器,每 x 分钟调用一个函数来获取数据(我们称之为 getData()),第一次调用 getData() 时经纬度为 0,但第二次、第三次等。他们有值。
当我在模拟器中更新坐标(在 运行 时间内)时,我确实得到了经纬度的更新值,但它是第一个 运行 纬度和经度总是是 0。我的代码如下所示:
let locationManager = CLLocationManager()
var getDataGroup = dispatch_group_create()
override func viewDidLoad() {
super.viewDidLoad()
dispatch_group_enter(getDataGroup)
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
dispatch_group_leave(getDataGroup)
dispatch_group_wait(getDataGroup, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_main_queue()) {
self.getData()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
if (error != nil){
println("Error: " + error.localizedDescription)
return
}
if (placemarks.count > 0){
let pm = placemarks[0] as! CLPlacemark
self.displayLocationInfo(pm)
}
else{
println("Error with location data")
}
})
}
func displayLocationInfo (placemark : CLPlacemark){
self.locationManager.stopUpdatingLocation()
lat = String(stringInterpolationSegment: placemark.location.coordinate.latitude)
long = String(stringInterpolationSegment: placemark.location.coordinate.longitude)
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Error: " + error.localizedDescription)
}
func getData(){
// Do stuff with lat and long...
}
出于某种原因,第一个 运行 lat 和 long 均为 0,其余 运行s 它们具有有效值。问题是 getData 在 locationManager 和 displayLocationInfo 方法之前被调用,即使我出于某种原因在调用 getData() 之前添加了 self.locationManager.startUpdatingLocation()。
我不太明白你的代码应该做什么。
您的 viewDidLoad 中没有 GCD 代码的原因。只需创建位置管理器的实例并告诉它开始更新您的位置。
一旦位置可用,就会调用您的 didUpdateLocations 方法。使用您在该方法中获得的位置数组中的最后一个位置 - 这将是最近的。
我建议在使用之前检查位置的 horizontalAccuracy。通常前几个位置读数非常糟糕,然后读数慢慢稳定下来。水平精度读数实际上是给出读数可能区域的半径。如果你得到 1 公里,这意味着你的位置可以在半径为 1 公里的圆圈内的任何地方。您可能想要丢弃那么差的读数,等待几百米以内(或更远)的读数。
您的 viewDidLoad 方法正在调用方法 getDeparturesAtStop,并且该方法可能会在第一次调用 didUpdateLocations 触发之前被调用。 (您没有显示该方法的作用。)
获得零的代码在哪里 lat/long?