Отслеживание расстояния CLLocation начинается неправильно

Я новичок в Swift (и на этом сайте, извините, если я делаю что-то не так), и я пытаюсь создать работающее приложение, которое отслеживает местоположение пользователя. Хотя функция, которую я использовал для отслеживания расстояния, работает, она не начинается с 0. Когда я нажимаю кнопку пуска, расстояние начинается со случайного числа, а затем начинается отслеживание оттуда.

Мой вопрос: есть ли что-то, к чему я не обращаюсь правильно? Если так, есть ли способ исправить это, чтобы отслеживание было более точным? Вот что у меня так далеко:

override func viewDidLoad() {
    super.viewDidLoad()


    stopwatchLabel.text = "00:00.00"
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.delegate = self

    locationManager.requestAlwaysAuthorization()
    locationManager.activityType = .fitness
   locationManager.distanceFilter = 10.0
    mapView.showsUserLocation = true
    startLocation = nil

    // Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Location Delegate Methods


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
    let location = locations.last
    let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
    let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002))
    self.mapView.setRegion(region, animated: true)


    if startLocation == nil {
        startLocation = locations.first
    }
    var distance = startLocation.distance(from: location!)
    let lastDistance = location?.distance(from: location!)
    distance += lastDistance!
    distanceString = "\(distance)"
    distanceLabel.text = distanceString


}

Вот как выглядит приложение:

экран запуска

Я понимаю, что другие люди задавали подобные вопросы, но у них либо нет ответа, либо они написаны на другом языке (например, Objective-C). Если на этот вопрос уже был дан ответ, и я просто упускаю его из виду, кто-нибудь может дать мне ответ? Спасибо!

2 ответа

Решение

Когда менеджер местоположений запускается, первое возвращенное местоположение - это кэшированное, последнее известное местоположение. Вы должны проверить это с помощью временной метки, а также проверить уровень точности, который возвращается. Как то так в вашем didUpdateLocations делегат:

let newLocation = locations.last

    let timeDiff = newLocation?.timestamp.timeIntervalSinceNow

let accuracyNeeded:CLLocationAccuracy=100.0

    if timeDiff < 5.0 && (newLocation?.horizontalAccuracy)!<=accuracyNeeded{
        //your code here
    }

Вы должны дать датчикам время прогреться.

Вот типичный didUpdateLocations реализация. Мы отслеживаем как время, прошедшее с того момента, как мы начали обновлять местоположения, так и улучшение горизонтальной точности по мере прогрева датчиков. Если горизонтальная точность не улучшается в разумные сроки, мы сдаемся.

Вам понадобится nil собственность, а Date?, называется startTimeи константы REQ_TIME а также REQ_ACC, self.stopTrying() отключает обновления и сбрасывает startTime в nil,

        let loc = locations.last!
        let acc = loc.horizontalAccuracy
        let time = loc.timestamp
        let coord = loc.coordinate
        if self.startTime == nil { // Date? property, keep track of time
            self.startTime = Date()
            return // ignore first attempt
        }
        let elapsed = time.timeIntervalSince(self.startTime)
        if elapsed > REQ_TIME { // required time before giving up
            self.stopTrying()
            return
        }
        if acc < 0 || acc > REQ_ACC { // desired accuracy
            return // wait for the next one
        }
        // got it
        print("You are at \(coord.latitude) \(coord.longitude)")
Другие вопросы по тегам