Dear all,
I created a workout app for Inline Skating (iOS 15, watchOS 8). Motivation behind is that currently Apple's Training App doesn't record a route for Inline Skating. So I modified the example app for doing Skating Workouts and track the route.
I'm currently only testing on simulator because I don't have a device with iOS 15 and watchOS 8. At least until tomorrow.
My question now is: The location simulation gives every time one single location in the respective delegate method func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
you have to process. Even the updated location is an array of CLLocation
. Currently, I consider only this one location but my guess is in the real world with real processing I get more than one location in the array. Am I right?
My next question is, in the next call of this method, are there old locations in the array or just the new ones which have to be processed?
I add the samples (distanceWalkingRunning) in this method because I want to show the current distance traveled in the workout. But if there are more than one location in the array my current approach doesn't work. :)
PS: I added the #if simulator line because the simulator seems sometimes to change locations in an erratic way.
This is my current delegate method:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newPoint = locations.last
//Check if the latest location was received after session started else return
if let newPoint = newPoint, let startDate = workoutSession?.startDate {
if newPoint.timestamp < startDate {
lastPoint = nil
return
}
}
if self.lastPoint == nil {
self.lastPoint = newPoint
}
// Filter the raw data.
// Seems useless for only one location.
let filteredLocations = locations.filter { (location: CLLocation) -> Bool in
location.horizontalAccuracy <= 50.0
}
guard !filteredLocations.isEmpty else { return }
// Add the filtered data to the route.
routeBuilder?.insertRouteData(filteredLocations) { (success, error) in
if let error = error {
print("❌ \(error.localizedDescription)")
}
}
var d: CLLocationDistance = 0
if let newPoint = newPoint, let lastPoint = self.lastPoint {
d = lastPoint.distance(from: newPoint)
self.lastPoint = newPoint
}
#if targetEnvironment(simulator)
guard d < 50 else { return }
#endif
let quantity = HKQuantity(unit: HKUnit.init(from: .meter), doubleValue: d)
if let startDate = workoutSession?.startDate {
let sample = HKQuantitySample(type: HKQuantityType( .distanceWalkingRunning), quantity: quantity, start: startDate, end: Date.now)
workoutBuilder?.add([sample], completion: { success, error in
if let error = error {
print("❌ \(error.localizedDescription)")
}
})
}
}