CoreLocation?

Hi all:


I am rying to make a very simple swift 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 happens and I don't know why...


Full code below, and I added the following keys to the 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

Answered by WatchDev2015 in 312505022

Solved! I had to add the Authorization code to the iPhone app, run there, set the authorization, then run the watch app.

Have you checked your code against the recommendations in this article? Seems like an outdoor workout may fit your use-case.

https://developer.apple.com/documentation/healthkit/workouts_and_activity_rings/running_workout_sessions

Accepted Answer

Solved! I had to add the Authorization code to the iPhone app, run there, set the authorization, then run the watch app.

CoreLocation?
 
 
Q