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
IBOutlet
s 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
:
1 2 3 4 5 6 7 |
// Please sir, may I know where I am? if(CLLocationManager.authorizationStatus() != CLAuthorizationStatus.AuthorizedWhenInUse) { self.locationManager.requestWhenInUseAuthorization() } |
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.
1 2 3 4 5 |
// 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:
1 2 3 |
// 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:
1 2 |
// 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
/** 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!