Reputation: 33
Can anyone provide me with a short snippet that will return me the magnetic heading of the iPhone? I do not want Objective-C please. I need it in Swift.
I have written these lines so far but it does not return me any value:
let locManager = CLLocationManager()
locManager.desiredAccuracy = kCLLocationAccuracyBest
locManager.requestWhenInUseAuthorization()
locManager.startUpdatingLocation()
locManager.startUpdatingHeading()
locManager.headingOrientation = .portrait
locManager.headingFilter = kCLHeadingFilterNone
print(locManager.heading?.trueHeading.binade as Any)
Thanks!
Upvotes: 3
Views: 1982
Reputation: 93161
You didn't set the delegate for the location manager. iOS does not update your location right away. Rather, it will call a function provided by your delegate when it has a location / heading update. The reason behind this setup is efficiency. Instead of 10 apps having 10 different location managers competing for time on the GPS hardware, these 10 location managers will request to be notified when the GPS has an update.
Try this:
class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var label: UILabel!
var locManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locManager.desiredAccuracy = kCLLocationAccuracyBest
locManager.requestWhenInUseAuthorization()
locManager.headingOrientation = .portrait
locManager.headingFilter = kCLHeadingFilterNone
locManager.delegate = self // you forgot to set the delegate
locManager.startUpdatingLocation()
locManager.startUpdatingHeading()
}
// MARK: -
// MARK: CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Location Manager failed: \(error)")
}
// Heading readings tend to be widely inaccurate until the system has calibrated itself
// Return true here allows iOS to show a calibration view when iOS wants to improve itself
func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool {
return true
}
// This function will be called whenever your heading is updated. Since you asked for best
// accuracy, this function will be called a lot of times. Better make it very efficient
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
label.text = "\(newHeading.magneticHeading)"
}
}
Upvotes: 5