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