【问题标题】:Swift CLLocation does not update location at startupSwift CLLocation 不会在启动时更新位置
【发布时间】:2015-05-24 19:10:49
【问题描述】:

我有一个应用程序,我想在 viewDidLoad 中获取用户位置,然后我将 lat 和 long 存储在变量中,并在函数中使用它们来根据用户的位置获取数据。我有一个计时器,它每 x 分钟调用一个函数来获取数据(我们称之为 getData()),第一次调用 getData() 时,lat 和 long 为 0,但第二次、第三次等等。他们有价值观。

当我在模拟器中更新坐标(在运行时)时,我确实得到了 lat 和 long 的更新值,但它是第一次运行时 lat 和 long 始终为 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,其余运行它们具有有效值。问题是 getData 在 locationManager 和 displayLocationInfo 方法之前被调用,即使我出于某种原因在调用 getData() 之前添加了 self.locationManager.startUpdatingLocation()。

【问题讨论】:

  • 什么时候调用 getData()?听起来您是在第一次收到对 didUpdateLocations 的回调之前调用它。在 GetData 和 didUpdateLocations 中放置一个断点,看看哪个先触发。
  • @KevinS 它只在 viewDidLoad 中调用,然后在计时器函数中调用。 getData 首先触发。定时器函数在 viewDidAppear 函数中。

标签: ios multithreading swift cllocationmanager


【解决方案1】:

我真的不明白你的代码应该做什么。

viewDidLoad 中的 GCD 代码没有任何原因。只需创建位置管理器的实例并告诉它开始更新您的位置。

然后,一旦位置可用,就会调用您的 didUpdateLocations 方法。使用通过该方法获得的位置数组中的最后一个位置 - 它将是最新的。

我建议在使用这些位置之前检查它们的水平精度。通常,最初的几个位置读数非常糟糕,然后读数慢慢稳定下来。水平精度读数实际上是一个半径,给出了可能的读数区域。如果你得到 1 公里,这意味着你的位置可能在半径为 1 公里的圆圈中的任何地方。您可能想要丢弃那些糟糕的读数并等待几百米(或更好)内的读数。

您的 viewDidLoad 方法正在调用方法 getDeparturesAtStop,并且该方法可能会在第一次调用 didUpdateLocations 之前被调用。 (您没有展示该方法的作用。)

获得零纬度/经度的代码在哪里?

【讨论】:

  • getDeparturesAtStop 是一个错字,应该是“getData()”。问题是 getData 在 locationManager 和 displayLocationInfo 方法之前被调用,即使我在调用 getData() 之前添加了 self.locationManager.startUpdatingLocation()
  • 您误解了它的工作原理。您调用 startUpdatingLocation,然后在某个时间之后,您的 didUpdateLocations 方法将开始被调用。可能是几秒钟后。您应该将需要位置的代码放在该方法中。
  • 是的,我注意到了这一点,现在我已经开始工作了。感谢您的帮助,我删除了 GCD。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
相关资源
最近更新 更多