How can I update the location in a specific time intervall?

Hey guys,


I am a newbie in xCode and Swift.


What is the goal?

I want to implement an iOS-App, which tracks my location every N seconds or minutes and log it to a file. The accuracy level should be the highest one. The app should be able to track my location when it is in foreground and in background.


Why do I want to track my location every N seconds or minutes?

Because I want to take care a little of the battery consumption.


What I have already implemented?

  • i have already made the "Capabilities" settings for the project -> Activate "Background Modes" and checked "Location updates" and "Background fetch".
  • I extended the info.plist with the following key/valeus -> "NSLocationAlwaysUsageDescription" and "NSLocationWhenInUseUsageDescription"
  • I have also implemented the CLLocationManagerDelegate like shown in the following lines


class LocationTableViewController : UITableViewController, CLLocationManagerDelegate {
  
    @IBOutlet weak var switchItem: UISwitch!  
  
    /
    var locationPoints =     [MKPointAnnotation]()
    var listOfLocationLogs:  [LocationLogData]?
    var timer:               NSTimer?
  
    lazy var locationManager:CLLocationManager! = {
        let manager = CLLocationManager()
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.delegate = self
        manager.requestAlwaysAuthorization()
        manager.pausesLocationUpdatesAutomatically = false
        /
      
        return manager
    }()
  
  
    /
    @IBAction func updatingLocationActivationChanged() {
        if switchItem.on {
            /
            println("Timer was started")
            locationManager.startUpdatingLocation()
        }
        else
        {
            /
            if (self.timer?.valid != nil) {
                self.timer?.invalidate()
                self.timer = nil
                println("Timer was active and will stop now")
            }*/
          
            locationManager.stopUpdatingLocation()
        }
    }
  
    func startLocationUpdate(){
        self.locationManager.startUpdatingLocation()
        println("Start updating location!")
    }
  
    /
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "showMapSegue") {
            var svc = segue.destinationViewController as! LocationDataShowOnMap
          
            svc.locationPoints = self.locationPoints
        }
    }
  
    /
    override func viewDidLoad() {
        super.viewDidLoad()
      
        /
        var refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: Selector("updateTable"), forControlEvents: UIControlEvents.ValueChanged)
        self.refreshControl = refreshControl
      
        switchItem.addTarget(self, action: "updatingLocationActivationChanged", forControlEvents: UIControlEvents.ValueChanged)
    }
  
    /
    /
    func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
      
        let annotation = MKPointAnnotation()
        annotation.coordinate = newLocation.coordinate
      
        /
        locationPoints.append(annotation)
      
        /
        while locationPoints.count > 150 {
            let annotationToRemove = locationPoints.first!
            locationPoints.removeAtIndex(0)
        }
      
      
        /
        var locationLog           = LocationLogData()
        locationLog.timeStamp     = newLocation.timestamp
        locationLog.location      = newLocation
        locationLog.horizontalAcc = newLocation.horizontalAccuracy
        locationLog.verticalAcc   = newLocation.verticalAccuracy
        locationLog.speed         = newLocation.speed
        locationLog.direction     = newLocation.course
        locationLog.distanceFromPreviousLocation = newLocation.distanceFromLocation(oldLocation)
      
        /
        if listOfLocationLogs == nil
        {
            listOfLocationLogs = [LocationLogData]()
            listOfLocationLogs?.append(locationLog)
        }
        else
        {
            listOfLocationLogs?.append(locationLog)
        }
      
      
        if UIApplication.sharedApplication().applicationState == .Active {
            /
            /
            /
            tableView.reloadData()
        }
        else
        {
            /
            NSLog("App is backgrounded. New location is %@", newLocation)
        }
      
        /
      
        /
        /
    }
  
    func locationManager(manager: CLLocationManager!, didFinishDeferredUpdatesWithError error: NSError!) {
        NSLog("Did finish deferred updates with error \(error.localizedDescription)")
    }
  
    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
        println("Location update did fail with error: \(error)")
      
        switch(error)
        {
            case kCLErrorDomain:
                println("ErrorDomain: KCLErrorDomain, Msg: \(error.localizedDescription), Reason: \(error.localizedDescription)")
                break;
            default:
                println("ErrorDomain: \(error.domain), Msg: \(error.localizedDescription), Reason: \(error.localizedDescription)")
          
        }
    }
  
    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        var locationStatus:String?
      
        switch status {
            case CLAuthorizationStatus.Restricted:
                locationStatus = "Access: Restricted"
                break
            case CLAuthorizationStatus.Denied:
                locationStatus = "Access: Denied"
                break
            case CLAuthorizationStatus.NotDetermined:
                locationStatus = "Access: NotDetermined"
                /
                break
            default:
                locationStatus = "Access: Allowed"
                /
        }
      
        NSLog(locationStatus!)
    }
  
    /
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if listOfLocationLogs != nil && listOfLocationLogs?.count >= 1
        {
            if(listOfLocationLogs?.count > 40)
            {
                return 10
            }
          
            return listOfLocationLogs!.count
        }
        else
        {
            return 0
        }
    }
  
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("locationLogEntryCell", forIndexPath: indexPath) as! LocationLogEntryCell
      
        let data:LocationLogData = listOfLocationLogs![indexPath.row]
        cell.lblLatitude.text = data.location.coordinate.latitude.description
        cell.lblLongitude.text = data.location.coordinate.longitude.description
        cell.lblLocationName.text = data.distanceFromPreviousLocation.description + " meters"
      
        return cell
    }
  
    /
    func updateTable(){
        tableView.reloadData()
        refreshControl?.endRefreshing()
    }
}



I hope you can help and support me as far as possible because I need this App

as a prototype for my Master Thesis.


Thank you so much,

Best Regards

numb88

To the best of my knowledge, the location services don't directly support that.


You can use the continuous tracking option at the cost of high battery usage, or use the option to watch for significant changes in location.

Neither operates on a specific time frequency.


You can simulate time intervals by using tracking results that reflect the time interval you want.


It may also be possible to use a timer and request additional background time, but that may or may not really work. Since iOS 7 that only gives you 2 minutes of background time, previously it was 11 minutes.


I would imagine the logic was that it was more important to know when changes in location happened than to always get location data at a specific time.

The continuous location feature is meant to be used for apps that give directions for travel, with the sigificant distance being used where high precision isn't important.

Ok thank you for your quick response.


I have already tried it by switching the location tracking on and off with timer support but I think that didn´t really work or that will deliver a lot of outlier.


I think I will try it as it is already implemented and test it on a real device.


I will close this thread in a few days. Maybe somebody still knows a workaround 🙂


Thanks

Best Regards

have you found any solution for this ??

Just something to think about is you should carefully check the power utilization of your app.


I have a navigation app that I have to disable location services for it when I'm nut using it, otherwise it drains the battery even when I haven't used it.

It works well in terms of functionality, but I rated it a 1 star in the app store because of the battery problem.

The best way I found for this was to send scheduled background push notifications from a server and update location when those are received.

How can I update the location in a specific time intervall?
 
 
Q