I am developing a running app in SwiftUI for watchOS. The problem is that when I start the run, the measuring works fine as 0.55 0.56 0.57
km, etc. Then it randomly freezes, and jumps from 0.57
straight to 0.71
. Even the total distance is sometimes inaccurate. When I look at the map of the run, I can sometimes see sharp corners and straight lines in curves, implying very inaccurate measurement. The OS is watchOS 8.0. I have tried kCLLocationAccuracyBest
to no avail.
I have used CLLocationManager
in an ObservableObject called DistanceObservable
, and I have this exact code in iOS app that measures the distance perfectly.
... @Published var distance: Double = 0.0
func startUpdate() {
self.manager = CLLocationManager()
self.manager?.delegate = self
self.manager?.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
self.manager?.requestWhenInUseAuthorization()
self.manager?.distanceFilter = 10.0
self.manager?.allowsBackgroundLocationUpdates = true
self.manager?.startUpdatingLocation()
}
Here is my watchOS
didUpdateLocations
method.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
var locations = locations
for newLocation in locations {
let howRecent = newLocation.timestamp.timeIntervalSinceNow
guard newLocation.horizontalAccuracy < 20 && abs(howRecent) < 10 else { continue }
if let lastLocation = locationList.last {
let delta = newLocation.distance(from: lastLocation)
if (delta < 60) { // To prevent inaccurate "jumps" in distance
distance = distance + delta
if UserDefaults.standard.value(forKey: "hasSet") as!Bool == false {
distance = 0
locations.removeAll()
UserDefaults.standard.setValue(true, forKey: "hasSet")
}
latPoints.append(Double(locationList.last!.coordinate.latitude))
lonPoints.append(Double(locationList.last!.coordinate.longitude))
}
}
locationList.append(newLocation)
}
}
Finally I use the @EnvironmentObject
in a SwiftUI View.
struct MyView: View {
@EnvironmentObject var loc: DistanceObservable
var body: some View {
Text("\(loc.distance)")
}
}