This article explains how to use CoreLocation and MapKit to display a location and speed on a map.
Last year I was in Japan and I was traveling on some seriously speedy trains. I was gutted (not happy) that the “bullet train” (Shinkansen, 新幹線) did not have a speedometer in the carriage that would let me know how fast I was going. But I had a laptop and a phone, so this is what I built…
Getting Started
To get started download the template project from Project Template. This is a simple, single view project with an MKMapView occupying the entire screen, overlaid with a UILabel to display the speed. These are linked to the mapView and speedLabel IBOutlets respectively.
May I Know Where I Am?
Location data is sensitive so we first must ask permission access it. Add the following to the `viewDidLoad` in `ViewController.swift`:
[swift]
// Please sir, may I know where I am?
if(CLLocationManager.authorizationStatus() !=
CLAuthorizationStatus.AuthorizedWhenInUse)
{
self.locationManager.requestWhenInUseAuthorization()
}
[/swift]
Tell Me Where I Am!
There was no `activityType` matching train and I had a power outlet at my seat, so I greedily configured my the best accuracy. To minimize the drain on the user’s battery you should try to choose the minimum `desiredAccuracy` that is sufficient for your needs.
Add the following code to configure the location manager to report at the best accuracy.
// Configure location manager
locationManager.activityType = CLActivityType.OtherNavigation
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
locationManager.startUpdatingLocation()
Show Me Where I Am
The location manager in the previous section tells us where we are in terms of longitude, latitude and speed, but to really visualize it we need a map.
Add the following code to map the current location:
// Configure map view
mapView.showsUserLocation = true
mapView.setUserTrackingMode(MKUserTrackingMode.Follow, animated: true)
Don’t Go Asleep On Me
To give constant display you can add the following:
// Stop the display going asleep
UIApplication.sharedApplication().idleTimerDisabled = true;
How Fast Am I Going
And finally… We come to the main part of the program. This function updates the label with the speed.
/**
Called when location changes, updates speed in speed label.
*/
func locationManager(manager: CLLocationManager, didUpdateToLocation newLocation: CLLocation, fromLocation oldLocation: CLLocation) {
if(newLocation.speed > 0) {
let kmh = newLocation.speed / 1000.0 * 60.0 * 60.0
if let speed = ViewController.numberFormatter.stringFromNumber(NSNumber(double: kmh)) {
self.speedLabel.text = "\(speed) km/h"
}
}
else {
self.speedLabel.text = "---"
}
}
Conclusion
The completed code for the tutorial can be found in the Shinkansen GitHub repository.
If you enjoyed this article please consider taking a moment to visit one of our sponsors!