1

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 !!

yerpy
  • 1,366
  • 3
  • 17
  • 44
  • You might want to consider using _location.course which gives you the direction based on gps coordinates. The magnetic heading can lose accuracy in my experience. – CoderMike Jan 31 '17 at 11:06

0 Answers0