【问题标题】:LocationManager locationsLocationManager 位置
【发布时间】:2017-01-05 20:18:30
【问题描述】:

我有一个列表,其中填充了来自 API 的数据。所以基本上流程是这样的:

当用户打开我的应用程序时:

if CLLocationManager.locationServicesEnabled() {
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = 20
        locationManager.startUpdatingLocation()
    }

然后在我的func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 中调用API 来获取数据。

但问题是 func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 有时最多可以调用 5-6 次,因此会有很多 API 调用,如果我只获得一个位置,那么我获得一个可能很远的位置的机会很大远离用户。

关于如何解决这个问题的任何想法?我基本上想要最好的位置,并尽可能少地调用 API,这是最好的。

【问题讨论】:

  • 只是几个想法:(a) 限制您自己的应用程序以每分钟最多发出 n 个请求; (b) 每个CLLocation 都有一个horizontalAccuracy 属性。如果它太大,忽略位置
  • 好评@CodeDifferent,关于horizontalAccuracy 的想法,位置管理器接受的最低准确度是多少?以便我知道我可以忽略什么。
  • 您必须进行实验才能找到答案。 The National Library of Medicine 引用了一项研究,称 iPhone 3G 的准确度约为 8 米。那是在 2009 年。

标签: swift position locationmanager


【解决方案1】:

基本上,如果您想避免在func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 调用 API,您需要考虑一些控制:

  • 在收到的位置之间创建时间间隔
  • “改善”您的 horizontalAccuracydistanceFilter

请记住,您始终需要避免:

  • 避免零位置
  • 位置无效
  • 位置无效
  • 位置乱码
  • 缓存位置(在您启动 locationManager 之前)

代码示例:

protocol MyLocationManagerDelegate {
    func locationControllerDidUpdateLocation(location: CLLocation)
}

final class MyLocationManager: NSObject, CLLocationManagerDelegate {

    var oldLocation: CLLocation?
    let kTimeFilter = Double(10)                  //avoid locations for each kTimeFilter seconds
    let kValidDistanceToOldLocation = Double(100)  //avoid location less than kValidDistanceToOldLocation meters
    var startDate: NSDate?
    var delegate: MyLocationManagerDelegate?


    func isValidLocation(newLocation newLocation: CLLocation?, oldLocation: CLLocation?) -> Bool {

        // avoid nil locations
        if newLocation == nil {
            return false
        }

        //avoid invalid locations
        if newLocation!.coordinate.latitude == 0 || newLocation!.coordinate.longitude == 0 {
            return false
        }

        //avoid invalid locations
        if (newLocation!.horizontalAccuracy < 0){
            return false
        }

        if oldLocation != nil {

            let distance = newLocation!.distanceFromLocation(oldLocation!)

            if fabs(distance) < kValidDistanceToOldLocation {
                return false
            }

            //avoid out-of-order location.
            let secondsSinceLastPoint = newLocation!.timestamp.timeIntervalSinceDate(oldLocation!.timestamp)
            if secondsSinceLastPoint < 0 || secondsSinceLastPoint < kTimeFilter {
                return false
            }
        }

        //avoid cached locations (before you start the locationManager)
        let secondsSinceManagerStarted = newLocation!.timestamp.timeIntervalSinceDate(startDate!)
        if secondsSinceManagerStarted < 0 {
            return false
        }

        return true
    }

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

        let newLocation = locations.last

        if isValidLocation(newLocation: newLocation, oldLocation:oldLocation) || oldLocation == nil {
            self.delegate?.locationControllerDidUpdateLocation(newLocation!)
            oldLocation = newLocation
        }

    }

}

class ViewController: UIViewController, MyLocationManagerDelegate {


    override func viewDidLoad() {
        super.viewDidLoad()

        let location = MyLocationManager()
        location.delegate = self

    }

    func locationControllerDidUpdateLocation(location: CLLocation) {
        //Api Call
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多