Hi all:
I am rying to make a very simple app for the Watch to track distance travlled (learning exercise), and I followed this tutorial which worked perfectly:
https://www.raywenderlich.com/155772/make-app-like-runkeeper-part-1-2
However, when I tried to use the code in a Watchkit app, it does not work. The call to
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
never happesn and I don't know why...
Full code below, and I added the following keys to teh watchkit Extension PLIST:
Privacy - Location Always Usage Description
Privacy - Location Always and When in Use Usage Description
Privacy - Location When In Use Usage Description
Can anyone make any suggestions?
import WatchKit
import Foundation
import CoreLocation
class InterfaceController: WKInterfaceController, CLLocationManagerDelegate
{
@IBOutlet var distanceLabel: WKInterfaceLabel!
@IBOutlet var timeLabel: WKInterfaceLabel!
@IBOutlet var paceLabel: WKInterfaceLabel!
@IBOutlet var cmdStart: WKInterfaceButton!
var locationManager: CLLocationManager = CLLocationManager()
private var locationList: [CLLocation] = []
private var distance = Measurement(value: 0, unit: UnitLength.meters)
private var seconds = 0
private var timer: Timer?
var Started = false
var startLocation: CLLocation!
var lastLocation: CLLocation!
override func awake(withContext context: Any?)
{
super.awake(withContext: context)
// Configure interface objects here.
}
override func willActivate()
{
// This method is called when watch view controller is about to be visible to user
super.willActivate()
//locationManager.requestWhenInUseAuthorization()
// For use when the app is open & in the background
locationManager.requestAlwaysAuthorization()
}
override func didDeactivate()
{
// This method is called when watch view controller is no longer visible
super.didDeactivate()
timer?.invalidate()
locationManager.stopUpdatingLocation()
}
@IBAction func cmdStart_Tap()
{
start()
}
private func start()
{
if (!Started)
{
Started = true
cmdStart.setTitle("Stop")
//launchPromptStackView.isHidden = true
//dataStackView.isHidden = false
//startButton.isHidden = true
//stopButton.isHidden = false
seconds = 0
distance = Measurement(value: 0, unit: UnitLength.meters)
locationList.removeAll()
updateDisplay()
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
self.eachSecond()
}
startLocationUpdates()
}
else
{
locationManager.stopUpdatingLocation()
}
}
func eachSecond()
{
seconds += 1
updateDisplay()
}
private func updateDisplay()
{
let formattedDistance = FormatDisplay.distance(distance)
let formattedTime = FormatDisplay.time(seconds)
let formattedPace = FormatDisplay.pace(distance: distance,
seconds: seconds,
outputUnit: UnitSpeed.minutesPerMile)
//distanceLabel.setText("Distance: \(formattedDistance)")
//timeLabel.setText("Time: \(formattedTime)")
//paceLabel.setText("Pace: \(formattedPace)")
distanceLabel.setText("\(formattedDistance)")
timeLabel.setText("\(formattedTime)")
paceLabel.setText("\(formattedPace)")
}
private func startLocationUpdates()
{
if CLLocationManager.locationServicesEnabled()
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
locationManager.distanceFilter = 10
}
else
{
print("Location services not enabled")
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
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)
distance = distance + Measurement(value: delta, unit: UnitLength.meters)
}
locationList.append(newLocation)
}
}
} //end of Class