CLLocationManager 获取位置很慢,Swift

Posted

技术标签:

【中文标题】CLLocationManager 获取位置很慢,Swift【英文标题】:CLLocationManager is slow getting location, Swift 【发布时间】:2017-07-03 21:20:20 【问题描述】:

我正在创建这个应用程序,它需要获取用户位置 - 一切正常,问题是,从接受使用位置服务到获得实际位置需要 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 连接,所以我知道这不是因为互联网很慢,或者它的连接不好......

有人有想法吗? :)

最好的问候!

【问题讨论】:

尝试设置精度并使用 locationManager.startUpdatingLocation()。我这样做,并在一秒钟内得到答案(在设备上)。 太棒了! locationManager.startUpdatingLocation() 成功了!我用 .requestLocation() 交换了它,现在它的工作就像一个魅力!谢谢@JensPeter - 想给你正确的答案,但我不能作为评论:/写一个答案,我会接受它:) 【参考方案1】:

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

【讨论】:

但是 requestLocation 的目的是只获取一次位置。否则它继续。给出位置直到它停止,结果它耗尽了电池【参考方案2】:

来自requestLocation()的文档:

此方法立即返回。调用它会导致位置管理器获取位置修复(可能需要几秒钟),并使用结果调用委托的 locationManager(_:didUpdateLocations:) 方法。

Source

所以基本上,你的代码一切都很好,这就是框架的构建方式。

【讨论】:

根据我的经验,requestLocation() 与 startUpdatingLocation() 相比返回结果要慢得多(2x-3x) 是的,根据我的经验,requestLocation() 也比 startUpdatingLocation() 慢得多。我不知道为什么,但我认为这与位置准确性有关。也许 requestLocation 每次都试图超级准确,而 startUpdatingLocation 不太准确?我不确定…… requestLocation() 很慢,因为它会启动位置服务,找到位置,当它找到位置时,位置服务就会停止。如果您使用 startUpdatingLocation() 您的位置会频繁更新(每 N 秒),并且因此会消耗更多电池。所以考虑一下你是如何使用它的。如果您使用 startUpdatingLocation() 则可能在收到位置后使用 stopUpdatingLocation() 停止它...【参考方案3】:

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

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

如果没有 startUpdatingLocation() 地理位置大约需要 5 秒,使用它,请求几乎立即执行。

【讨论】:

【参考方案4】:

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

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() 的组合应该在根视图控制器准备就绪之前返回一个位置。 B 经理很可能会在用户启动应用程序后返回一个位置。

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
        

    


【讨论】:

以上是关于CLLocationManager 获取位置很慢,Swift的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中使用 CLLocationManager 获取当前位置

使用 CoreLocation CLLocationManager 获取过去的位置

iPhone - CLLocationManager 在尝试获取当前位置时停止更新

获取用户当前位置坐标:MKMapItem vs CLLocationManager

CLLocationmanager 中的 GPS 位置更新

是否有任何方法可以在我的应用程序中不使用 CLLocationManager 委托来获取当前位置