ShinkansenSpeed: MapKit and CoreLocation in Swift

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!


About idz

A professional software engineer dabbling in iOS app development.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply