Is it the way to get heading from inside the didUpdateLocation method ? I am grapple with task which is about sending the data about user location to container class called Ping. The Ping class have to contain basics user location as well as with north heading.
- Is it the way to enable compass from code in iOS ?
My location service saving the data after period of time or degree turn of the device or distance traveled - also if we turn faster or we traveled the distance then timer going to be restarted.
I have not test it yet on physical device ( only simulator ) so I am not able to see If I am counting well traveled distance and the angle.
import Foundation
import CoreLocation
import CoreMotion
import UIKit
class LocationService: NSObject, CLLocationManagerDelegate {
var _locationManager: CLLocationManager!
var _motionManager: CMMotionManager!
var _timer = Timer()
var _heading: Double!
var _accuracy: Double!
var _latitude: Double!
var _longitude: Double!
var _velocity: Double!
var _startLocation: CLLocation!
var _lastLocation: CLLocation!
var _traveledDistance: Double = 0
var _seconds = 0
var _deferringUpdates: Bool = false
static let _instance : LocationService = LocationService()
public static var Instance : LocationService {
get{ return _instance}
}
public func InitLocationManager() {
_locationManager = CLLocationManager()
_locationManager.delegate = self
_locationManager.distanceFilter = 1000
_locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
_locationManager.requestAlwaysAuthorization()
_locationManager.startUpdatingLocation()
if CLLocationManager.headingAvailable() {
_locationManager.headingFilter = 5
_locationManager.startUpdatingHeading()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateHeading _newHeading: CLHeading) {
if _newHeading.headingAccuracy < 0 {
return
}
let _theHeading : CLLocationDirection = _newHeading.trueHeading > 0 ? _newHeading.trueHeading : _newHeading.magneticHeading
self._heading = _theHeading
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations _locations: [CLLocation]) {
let _location = _locations[0]
self._accuracy = _location.horizontalAccuracy
self._latitude = _location.coordinate.latitude
self._longitude = _location.coordinate.longitude
self._velocity = _location.speed
_timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(UpdateTimer), userInfo: nil, repeats: true)
if _startLocation == nil {
_startLocation = _locations.first
} else {
if let _lastLocation = _locations.last {
let _distance = _startLocation.distance(from: _lastLocation)
let _lastDistance = _lastLocation.distance(from: _lastLocation)
_traveledDistance += _lastDistance
if _traveledDistance <= 100 {
PostNotificationWithLocation()
_traveledDistance = 0
_timer.invalidate()
}
}
}
_lastLocation = _locations.last
_motionManager = CMMotionManager()
if _motionManager?.isDeviceMotionAvailable == true {
_motionManager?.deviceMotionUpdateInterval = 0.1
let queue = OperationQueue()
_motionManager?.startDeviceMotionUpdates(to: queue, withHandler: { (_motion, _error) in
if let attitude = _motion?.attitude {
if(attitude.pitch == 30/M_PI) {
self.PostNotificationWithLocation()
self._timer.invalidate()
}
}
})
}
_locationManager.stopUpdatingLocation()
}
func PostNotificationWithLocation() -> Void {
NotificationCenter.default.post(name: LOCATION_NOTIFICATION, object: nil, userInfo: ["latitude":_latitude, "longitude":_longitude, "velocity":_velocity, "traveledDistance":_traveledDistance])
}
func UpdateTimer() {
_seconds += 1
if _seconds == 10 {
PostNotificationWithLocation()
_timer.invalidate()
_seconds = 0
}
}
}
Thanks in advance !!