CLLocationManager 获取位置很慢,Swift

CLLocationManager is slow getting location, Swift

我正在创建这个应用程序,它需要获取用户位置 - 它一切正常,问题是,从接受使用定位服务到获取实际位置大约需要 5 秒 - 是这正常吗? 我用过其他应用程序,速度更快..

我的代码如下所示:

override func viewDidLoad() {
    super.viewDidLoad()

    // Ask for Location-Authorisation from the User.
    self.locationManager.requestWhenInUseAuthorization()

    if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.requestLocation()
    }

    mapView.delegate = self

}



func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let locValue: CLLocationCoordinate2D = manager.location!.coordinate

    let initialLocation = CLLocation(latitude: locValue.latitude, longitude: locValue.longitude)

    self.centerMapOnLocation(initialLocation)
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
    print("could not get location")
}

但是从应用程序获取位置到放入centerMapOnLocation函数的时间,似乎是相当长。获取用户位置时会发生什么?我正在测试 wifi 连接,所以我知道这不是因为互联网速度慢,或者连接不好...

有人有想法吗? :)

此致!

来自 requestLocation() 的文档:

This method returns immediately. Calling it causes the location manager to obtain a location fix (which may take several seconds) and call the delegate’s locationManager(_:didUpdateLocations:) method with the result.

Source

所以基本上,您的代码一切正常,这就是框架的构建方式。

尝试设置精度并使用 locationManager.startUpdatingLocation()。我这样做,并在一秒钟内得到答案(在设备上)。

如果您不想延迟位置管理器的应用启动,请考虑部署两个位置管理器(在应用程序委托中),让一个负责快速生成位置,另一个负责准确生成位置:

locA.delegate = self
locA.desiredAccuracy = kCLLocationAccuracyThreeKilometers
locA.requestWhenInUseAuthorization()
locA.startUpdatingLocation() // quick and multiple

locB.delegate = self
locB.desiredAccuracy = kCLLocationAccuracyBest
locB.requestWhenInUseAuthorization()
locB.requestLocation() // slow and single

3 km 准确度与 startUpdatingLocation() 的组合应该 return 在根视图控制器准备好之前的一个位置。 B 管理器可能会在用户启动应用程序后很久 return 一个位置。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    switch manager {

    case locA:

        locA.stopUpdatingLocation()
        deviceLocation = locations.last! // set property with estimated loc

    case locB:
        deviceLocation = locations.last! // overwrite property with accurate loc

    default:
        break

    }

}

作为最后一层保护,您可以在客户端保留位置:

private var deviceLocation_: CLLocation?

var deviceLocation: CLLocation? {

    set {

        deviceLocation_ = newValue

        let c = ["lat": newValue.coordinate.latitude, "lon": newValue.coordinate.longitude]
        UserDefaults.standard.set(c, forKey: "app.yourApp.coordinates")

    } get {

        if let l = deviceLocation_ {
            return l
        } else if let def = UserDefaults.standard.object(forKey: "app.yourApp.coordinates") as? [String: Double],
            let lat = def["lat"],
            let lon = def["lon"] {
            return CLLocation(latitude: lat, longitude: lon)
        } else {
            return nil // or the coordinates to Lost island
        }

    }

}

在初始化位置管理器时,添加 startUpdatingLocation():

let manager = CLLocationManager()
 manager.delegate = self
 manager.requestWhenInUseAuthorization()
 manager.requestLocation()
 manager.startUpdatingLocation()

没有 startUpdatingLocation() 地理定位大约需要 5 秒,有了它,请求几乎立即执行。